Search code examples
jakarta-eejmswebsphereibm-mq

jms receive method doesnot stop when there is no message in Queue


I have tried to recieve the messages from queue as mentioned in the link. The queue may contain multilple messages. I want to read all at once.

Issue :

I used the below given approach. But when there is no message in the queue after 3minutes(180000 milliseconds), I couldnt see the control getting passed to else part inside while loop.

Beacuse of this I am not able to reach the finally block tom stop the connection.

As given in the link when there is no message, I should receive end-of-message-stream control message. But I dont get it.

Because of this else part inside while loop is not getting excecuted and finally block is never getting reached to close the connection

What can be the issue?

Approach:

import javax.naming.InitialContext;

import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.QueueSession;
import javax.jms.QueueReceiver;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;

public class Receiver
{
      @Resource(lookup = "jms/ConnectionFactory")
      private static QueueConnectionFactory connectionFactory;

      @Resource(lookup = "jms/Queue")
      private static Queue queue;

      public void readQueueMessages() {                                                                   
      try {
         // create a queue connection
         QueueConnection queueConn = connFactory.createQueueConnection();

         // create a queue session
         QueueSession queueSession = queueConn.createQueueSession(false,
         Session.AUTO_ACKNOWLEDGE);

        // create a queue receiver
         QueueReceiver queueReceiver = queueSession.createReceiver(queue);

         // start the connection
         queueConn.start();

         // receive a message
          while(true) {
          TextMessage message = (TextMessage) queueReceiver.receive(180000);
              if (message != null) { 
                      if (message instanceof TextMessage) {
                        / print the message
                          System.out.println("received: " + message.getText());
                      } else {
                             break; // when the end-of-message stream control is message is received, that cannnot be of Textmessage type. So the loop should terminate.
                      }
                 }
           }
        } catch(JMSException exp) {
           // Handle this exception
       } finally {      
            if(queueConn != null) {                                                     
                 // close the queue connection
                queueConn.close();
            }
       }

Solution

  • That link didn't say "As given in the link when there is no message, I should receive end-of-message-stream control message.", step 7 said the sending client needed to
    "Sends an empty control message to indicate the end of the message stream: producer.send(session.createMessage());
    Sending an empty message of no specified type is a convenient way to indicate to the consumer that the final message has arrived."
    So unless your message producer denotes the final message of a conversation with an untyped empty message like the example, your receiving client is not going to work as expected.