2

I am using Spring DefaultMessageListenerContainer and JMS Message Listener to consume messages from Solace Queue. Client Acknowledgement is set to true.

In case of exception messages remain in the queue since they were not acknowledged and these are not redelivered. New messages that were pumped post exception are processed.

Have read about using session.recover but how do we get handle to session . Also tried setting maxredelivery to 3 . But not working.

public void onMessage(Message message) {
 String text = null;
 ALNTLogger.trace(CLAZZ_NAME, "onMessage()", "Message Received:");
 try {
   TextMessage textMessage = (TextMessage) message;
   text = textMessage.getText();
   ALNTLogger.trace(CLAZZ_NAME, "onMessage()", "Message Received: " + text);

   Document xmlDocument = parseXml(text);
   Map < String, String > values = getValues(xmlDocument);
   saveValues(values);
   message.acknowledge();
 } catch (Exception ex) {
  ALNTLogger.error(CLAZZ_NAME, "onMessage()", "Failed to process message:" + text);
  throw new RuntimeException(ex);
 }
} 

Any help will be appreciated

Amit G
  • 51
  • 1
  • 3

1 Answers1

1

It is expected that the message is not redelivered when using CLIENT_ACKNOWLEDGE acknowledgement mode with a DefaultMessageListenerContainer.

The Spring documentation states the following:

The listener container offers the following message acknowledgment options:

  • "sessionAcknowledgeMode" set to "AUTO_ACKNOWLEDGE" (default): Automatic message acknowledgment before listener execution; no redelivery in case of exception thrown.
  • "sessionAcknowledgeMode" set to "CLIENT_ACKNOWLEDGE": Automatic message acknowledgment after successful listener execution; no redelivery in case of exception thrown.
  • "sessionAcknowledgeMode" set to "DUPS_OK_ACKNOWLEDGE": Lazy message acknowledgment during or after listener execution; potential redelivery in case of exception thrown.
  • "sessionTransacted" set to "true": Transactional acknowledgment after successful listener execution; guaranteed redelivery in case of exception thrown.

You can use the last option, transactional acknowledgements, in order to have the message redelivered when the onMessage() method does not return normally.

Alexandra Masse
  • 1,277
  • 1
  • 7
  • 11
  • So this means that when using a `MessageListenerContainer`, the only useful session mode is transactional, unless the application doesn't care about losing messages sometimes. Even worse, it's the default (`AUTO_ACKNOWLEDGE`) that messages are just lost if you have an exception... I wonder how many applications out there do that without knowing. – ddekany Feb 18 '18 at 22:53
  • The `AbstractMessageListenerContainer` JavaDocs were improved since then, so for example for `CLIENT_ACKNOWLEDGE` it says "best-effort redelivery in case of a user exception thrown". Why's that just a best-effort though... – ddekany Feb 18 '18 at 23:15