如何在JEE服务器(Wildfly)的JMS临时队列中创建监听器?

问题描述:

我想在Wildfly 10中使用JMS 2.0创建临时JMS队列,并且注入连接工厂。如何在JEE服务器(Wildfly)的JMS临时队列中创建监听器?

我使用@JMSConnectionFactory注入我的ConnectionFactory。这工作正常。

@Inject @JMSConnectionFactory("java:/jms/RemoteConnectionFactory") JMSContext jmsContext 

创建一个临时队列也能正常工作:

Destination jmsQueue = jmsContext.createTemporaryQueue(); 

创建出版商和出版信息工作好,以及:

JMSProducer producer = jmsContext.createProducer(); 
TextMessage msg = jmsContext.createTextMessage(Long.toString(new Date().getTime())); 
producer.send(jmsQueue, msg); 

但是,我怎么创建了一个监听器队列?由于临时队列未预定义,因此无法使用MDB。如果我尝试创建一个消费者,并分配一个消息监听器给它,我收到以下错误信息:

JMSConsumer consumer = jmsContext.createConsumer(jmsQueue); 
    consumer.setMessageListener(new MessageListener() { 
       ... 
       ... 
      }); 

错误跟踪:

Caused by: javax.jms.IllegalStateException: This method is not applicable inside the application server. See the J2EE spec, e.g. J2EE1.4 Section 6.6 
     at org.apache.activemq.artemis.ra.ActiveMQRASession.checkStrict(ActiveMQRASession.java:1452) 
     at org.apache.activemq.artemis.ra.ActiveMQRAMessageConsumer.setMessageListener(ActiveMQRAMessageConsumer.java:123) 
     at org.apache.activemq.artemis.jms.client.ActiveMQJMSConsumer.setMessageListener(ActiveMQJMSConsumer.java:59) 

这样看来,我不能明确地设定一个消息听众与JEE控制连接工厂。但考虑到它是一个临时队列,我无法创建一个MDB,因为在编译时不知道目的地。那么,我如何收听临时队列呢?

我只能通过使用JMS 1.0来解决这个问题。我有代码是这样的:

TopicConnectionFactory topicConnectionFactory; 
Topic topic; 
TopicConnection topicConnection; 

try { 
    InitialContext context = new InitialContext(); 
    topicConnectionFactory = (TopicConnectionFactory)jndi.lookup("jboss/DefaultJMSConnectionFactory"); 
    topic = (Topic)jndi.lookup("jms/myTopicName"); 

    topicConnection = topicConnectionFactory.createTopicConnection(); 

    TopicSession topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); 

    TopicSubscriber topicSubscriber = topicSession.createSubscriber(projectTopic, null, false); 
    topicSubscriber.setMessageListener(listenerClass); 
    topicConnection.start(); 
} 
... 

其中listenerClass是实现javax.jms.MessageListener类。

这利用了在standalone-full.xml内的Wildfly中定义的预定义的JMS连接工厂,所以我不需要设置一个明确的。

作为一个警告 - 我运行此代码的最后一次是在Wildfly 8中,所以有些事情可能已经发生了一些变化。另外,我没有使用远程连接,因此,可能会有一些差异。

+0

谢谢 - 我也试过,但仍然得到相同的异常抛出。不特别感到惊讶,因为客户端仍在使用相同的ActiveMARASession,无论它使用的是JMS2还是JMS1 facade。我无法想象这是没有合理的解决方案。 –

+0

为什么你需要一个临时队列呢?如果您希望容器为部署的整个生命周期提供mdb实例,那么这也需要队列存在,否则它们将附加到什么位置? –

+0

@willt我需要有一个发布/订阅队列,这对我的集群中的每个节点都是唯一的。队列必须在运行时的生命周期内存活;它不需要坚持重新启动。另外我不想手动管理这些队列。因此,有一个临时队列的想法......但是如果没有办法听到它,那么jee中的临时队列的目的是什么? –