WildFly 19中JMS Topic消费者接收null值的解决方法
问题描述
使用WildFly 19开发JMS Topic应用时,消费者接收的消息值为null。
Java代码实现
try { final Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory"); env.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080"); env.put(Context.SECURITY_PRINCIPAL, "jmsuser"); env.put(Context.SECURITY_CREDENTIALS, "Password1!"); namingContext = new InitialContext(env); ConnectionFactory connectionFactory = (ConnectionFactory) namingContext.lookup("jms/RemoteConnectionFactory"); Destination destination = (Destination) namingContext .lookup("jms/topic/myTopic"); context = connectionFactory.createContext("jmsuser", "Password1!"); context.createProducer().send(destination, "mymeninsgh city topic !"); System.out.println("Sent message successuflly "); JMSConsumer consumer = context.createConsumer(destination); String text = consumer.receiveBody(String.class, 5000); System.out.println("Received message with content " + text); } catch (Exception e) { System.out.println(e.getMessage()); throw e; } finally { if (namingContext != null) { namingContext.close(); } if (context != null) { context.close(); } }
WildFly Topic配置

程序运行日志
Sent message successuflly Received message with content null
解决方案
核心问题是Topic的消息发布逻辑是「先订阅、后接收」:你当前代码先发送消息,再创建消费者订阅,此时消息已经被Broker处理完成,不会推送给后续才订阅的消费者。
按以下方式修改即可解决:
- 调整代码执行顺序:先初始化消费者完成订阅,再执行消息发送操作。
- (可选)如果需要接收离线期间的历史消息,可创建持久化订阅,确保消息会被Broker保存至消费者上线后接收。
修改后的代码示例
try { final Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory"); env.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080"); env.put(Context.SECURITY_PRINCIPAL, "jmsuser"); env.put(Context.SECURITY_CREDENTIALS, "Password1!"); namingContext = new InitialContext(env); ConnectionFactory connectionFactory = (ConnectionFactory) namingContext.lookup("jms/RemoteConnectionFactory"); Destination destination = (Destination) namingContext.lookup("jms/topic/myTopic"); context = connectionFactory.createContext("jmsuser", "Password1!"); // 先创建消费者完成订阅 JMSConsumer consumer = context.createConsumer(destination); // 再发送消息 context.createProducer().send(destination, "mymeninsgh city topic !"); System.out.println("Sent message successfully "); String text = consumer.receiveBody(String.class, 5000); System.out.println("Received message with content " + text); } catch (Exception e) { System.out.println(e.getMessage()); throw e; } finally { if (namingContext != null) { namingContext.close(); } if (context != null) { context.close(); } }
持久化订阅配置(可选)
如果需要支持离线接收消息,可使用持久化订阅:
// 设置客户端唯一ID context.setClientID("myUniqueClientId"); // 创建持久化订阅,指定订阅名称 JMSConsumer consumer = context.createDurableConsumer((Topic) destination, "myDurableSubscription");
WildFly默认支持Topic的持久化订阅,无需额外修改服务端配置。
内容的提问来源于stack exchange,提问作者Masum Mia
相关产品推荐
相关产品推荐

