2016-08-18 97 views
0

因此,我正在關注使用JBoss的Java消息服務上的this youtube教程。我的代碼與視頻相同,但是當我運行我的TopicConsumerTopicProducer應用程序時,它們都會終止並且不會保持活動狀態,無法接收我的消息。我讀setMessageListener會創建一個新的線程,所以即使主線程被終止但應收到的消息仍然沒有收到消息。JMS消費者終止並且沒有收到消息

我發現它不叫onMessage,是不是因爲TopicConsumer在得到機會之前被終止?

我已經運行了我的JBoss 5.0服務器,就像在視頻中我首先運行TopicConsumer(但它在打印語句不同於視頻後終止),然後TopicProduver(它也在打印語句之後終止)不會收到我的消息。

謝謝。

TopicConsumer.java

package jmspubsubtutorial; 

import java.util.Properties; 

import javax.jms.JMSException; 
import javax.jms.Message; 
import javax.jms.MessageListener; 
import javax.jms.TextMessage; 
import javax.jms.Topic; 
import javax.jms.TopicConnection; 
import javax.jms.TopicConnectionFactory; 
import javax.jms.TopicSession; 
import javax.naming.Context; 
import javax.naming.InitialContext; 
import javax.naming.NamingException; 

public class TopicConsumer implements MessageListener { 

    public static void main(String[] args) throws JMSException, NamingException{ 
     System.out.println("---Starting TopicConsumer---"); 
     Context context = TopicConsumer.getInitialContext(); 
     TopicConnectionFactory topicConnectionFactory = (TopicConnectionFactory) context.lookup("ConnectionFactory"); 
     Topic topic = (Topic) context.lookup("topic/JMS_tutorial"); 
     TopicConnection topicConnection = topicConnectionFactory.createTopicConnection(); 
     TopicSession topicSession = topicConnection.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE); 

     topicSession.createSubscriber(topic).setMessageListener(new TopicConsumer()); 
     topicConnection.start(); 

     System.out.println("---Exiting TopicConsumer---"); 
    } 

    @Override 
    public void onMessage(Message message) { 
     System.out.println("--- onMessage ---"); 
     try { 
      System.out.println("Incoming message: " + ((TextMessage)message).getText()); 
     } catch (JMSException e) { 
      System.out.println("onMessage failed"); 
      e.printStackTrace(); 
     } 
    } 

    public static Context getInitialContext() throws JMSException, NamingException { 
     Properties props = new Properties(); 
     props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); 
     props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming"); 
     props.setProperty("java.naming.provider.url", "localhost:1099"); 
     Context context = new InitialContext(props); 
     return context; 
    } 
} 

TopicProducer.java

package jmspubsubtutorial; 

import javax.jms.JMSException; 
import javax.jms.TextMessage; 
import javax.jms.Topic; 
import javax.jms.TopicConnection; 
import javax.jms.TopicConnectionFactory; 
import javax.jms.TopicPublisher; 
import javax.jms.TopicSession; 
import javax.naming.Context; 
import javax.naming.NamingException; 

public class TopicProducer { 

    public static void main(String[] args) throws JMSException, NamingException{ 
     System.out.println("---Starting TopicProducer---"); 
     Context context = TopicConsumer.getInitialContext(); 
     TopicConnectionFactory topicConnectionFactory = (TopicConnectionFactory) context.lookup("ConnectionFactory"); 
     Topic topic = (Topic) context.lookup("topic/JMS_tutorial"); 
     TopicConnection topicConnection = topicConnectionFactory.createTopicConnection(); 
     TopicSession topicSession = topicConnection.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE); 
     topicConnection.start(); 
     TopicProducer topicProducer = new TopicProducer(); 
     String text = "message 1 from TopicProducer..."; 
     topicProducer.sendMessage(text, topicSession, topic); 

     System.out.println("---Exiting TopicProducer---"); 
    } 

    public void sendMessage(String text, TopicSession topicSession, Topic topic) throws JMSException { 
     System.out.println("Send Message: " + text + " " + topicSession + " " + topic); 
     TopicPublisher topicPublisher = topicSession.createPublisher(topic); 
     TextMessage textMessage = topicSession.createTextMessage(text); 
     topicPublisher.publish(textMessage); 
     topicPublisher.close(); 
    } 
} 

回答

0

所以問題是,你是依靠JMS庫保持至少一個非守護線程,以保持您的應用程序在創建消費者並分配消息監聽器後仍然存活,但實際上並不保證它會執行任何此類事情。

的確,許多JMS提供程序確實試圖始終在內部運行單個非守護程序線程,但假設這總是如此,這不是真正可取的。你似乎發現你的特定提供者不會爲你做這件事,所以如果你想確保你的應用程序保持運行,你應該自己做這件事。