Search code examples
jmsactivemq-artemis

ActiveMQ Artemis QueueBrowser always returns false for Enumeration.hasMoreElements()


I have a JMS client that finds the messages in a queue, and one that refuses. The one that refuses always returns false for enum.hasMoreElements(). I can only conclude that I'm making a mistake in trying this in an if/else block with the consumer inactive. If I write a client that just uses the QueueBrowser (i.e. no MessageConsumer) then it works as advertised. I would appreciate the eye of a seasoned vet to help me understand.

// Consumer/Browser
TextMessage msgIn = session.createTextMessage();
boolean consumerBool = false;
if (consumerBool == true) {
   System.out.println("Consumer ready to consume ...");
   msgIn = (TextMessage)consumer.receive();
   System.out.println("Consumer received " + msgIn.getText());
} else {
   System.out.println("Starting QueueBrowser ... ");
   cn.start();
   QueueBrowser browser = session.createBrowser(queue);
   Enumeration enumm = browser.getEnumeration();
   boolean elementsBool = enumm.hasMoreElements();
   Queue temp = browser.getQueue();
   System.out.println("Browser using queue = " + temp);
   System.out.println("enumm.hasMoreElements() return = " + elementsBool);

   while(enumm.hasMoreElements()) {
       msgIn = (TextMessage)enumm.nextElement();
       System.out.println("Browsed msg [" + msgIn.getText() + "]");
   }
   browser.close();
}

cn.close();
session.close();

In the following the queue is correct, and there are messages in it, but the hasMoreElements() is false. You can see I did the obligatory cn.start(). I started it right before creating the enum and browser.


Solution

  • This is almost certainly caused by the consumer pre-fetching messages from the broker which means those messages are not available to be browsed.

    Messages which have been dispatched to a consumer but have not yet been acknowledged are referred to as "in delivery" and you can see how many messages are in this state by inspecting the "DeliveringCount" metrics on the queue (e.g. via the web admin console). Such messages are not available to other consumers or browsers since they've already been "claimed," so to speak.

    Dispatching groups of messages to a consumer is a performance optimization so that the consumer doesn't have to make a round-trip across the network for every single message. If you're using the core JMS client then you can control this behavior via the consumerWindowSize parameter on the connection URL. You can read more about this in the documentation.