Reputation: 15
I just finished a tutorial on JMS, so it's super new to me and I'm trying to understand the basics. I'm using ActiveMQ Artemis if that matters. I created two simple applications, one named Producer
and the other named Consumer
. I run Producer
first then run Consumer
. The Consumer
application never terminates and does not print the messages to the console. Weirdly, if I do not manually terminate Consumer
and run Producer
a second time, then I see the messages that Consumer
should have received printed on the console. What's going on here? How do I get Consumer
to receive and print messages from Producer
?
Here's Producer
:
public class Producer {
public static void main(String[] args) throws Exception {
InitialContext initialContext = null;
Connection connection = null;
initialContext = new InitialContext();
ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory");
connection = cf.createConnection();
Session session = connection.createSession();
Queue queue = (Queue) initialContext.lookup("queue/myQueue");
Topic topic = (Topic) initialContext.lookup("topic/myTopic");
MessageProducer queueProducer = session.createProducer(queue);
MessageProducer topicProducer = session.createProducer(topic);
TextMessage queueMessage = session.createTextMessage("This message is for the queue2");
TextMessage topicMessage = session.createTextMessage("This message is for the topic2");
queueProducer.send(queueMessage);
topicProducer.send(topicMessage);
System.out.println("Message to queue sent: "+ queueMessage.getText());
System.out.println("Message to topic sent: "+ topicMessage.getText());
initialContext.close();
}
}
Here's Consumer
:
public class Consumer {
public static void main(String[] args) throws Exception {
InitialContext initialContext = null;
Connection connection = null;
initialContext = new InitialContext();
ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory");
connection = cf.createConnection();
Session session = connection.createSession();
Queue queue = (Queue) initialContext.lookup("queue/myQueue");
Topic topic = (Topic) initialContext.lookup("topic/myTopic");
MessageConsumer queueConsumer = session.createConsumer(queue);
MessageConsumer topicConsumer1 = session.createConsumer(topic);
MessageConsumer topicConsumer2 = session.createConsumer(topic);
connection.start();
TextMessage messageReceivedByQueueConsumer = (TextMessage) queueConsumer.receive();
TextMessage messageReceivedByTopicConsumer1 = (TextMessage) topicConsumer1.receive();
TextMessage messageReceivedByTopicConsumer2 = (TextMessage) topicConsumer2.receive();
System.out.println("Message received by queue consumer: "+ messageReceivedByQueueConsumer.getText());
System.out.println("Message received by topic consumer 1: "+ messageReceivedByTopicConsumer1.getText());
System.out.println("Message received by topic consumer 2: "+ messageReceivedByTopicConsumer2.getText());
connection.close();
initialContext.close();
}
}
Upvotes: 0
Views: 2167
Reputation: 35008
What you're observing is, in fact, the expected behavior.
Since you run the Producer
application first a message is being sent to a queue and a topic when no consumer/subscriber exists on either. The message sent to the queue is stored in the queue because that's how JMS queues work. The message sent to the topic is discarded since there are no subscriptions to receive the message. Again, this is how JMS topics work.
Then when your Consumer
application runs the queueConsumer
receives the message sent to the queue, but since you're invoking receive()
with no timeout on topicConsumer1
the application will simply block forever since there are no messages in the topic consumer's subscription. This blocking prevents the message received from the queue from being printed.
You should run your consuming application first and then run your producer while the consuming application is still running. Then you should see all the messages received and printed as you assumed they would be.
Upvotes: 2