Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a simple Spring JMS client acknowledge to work

Just starting to get my head around getting JMS ActiveMQ Acknowledgements working in Spring. So far I have a consumer working perfectly, with the exception that when I don't acknowledge the message, it's still taken from the queue (I expect it to stay there or end in a dead letter queue).

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jms="http://www.springframework.org/schema/jms"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd">

    <!-- A JMS connection factory for ActiveMQ -->
    <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"
    p:brokerURL="failover://(tcp://jms1:61616,tcp://jms2:61616)?randomize=false&amp;jms.redeliveryPolicy.maximumRedeliveries=5" />

    <!-- A POJO that implements the JMS message listener -->
    <bean id="simpleMessageListener" class="com.company.ConsumerClass" />

    <!-- A JMS namespace aware Spring configuration for the message listener container -->
    <jms:listener-container
            container-type="default"
            connection-factory="connectionFactory"
            acknowledge="client"
            concurrency="10-50"
            cache="consumer">
        <jms:listener destination="someQueue" ref="simpleMessageListener" method="onMessage" />
    </jms:listener-container>
</beans>

In the ConsumerClass, my simple consumer looks something like this:

@Override public final void onMessage(Message message) {
    Object postedMessage = null;
    try {
        postedMessage = ((ObjectMessage) message).getObject();

        if (postedMessage.getClass() == SomeMessageType.class) {
            try {
                //Some logic here

                message.acknowledge();
                return; //Success Here
            } catch (MyException e) {
                logger.error("Could not process message, but as I didn't call acknowledge I expect it to end up in the dead message queue");
            }
        }
    } catch (JMSException e) {
        logger.error("Error occurred pulling Message from Queue", e);
    }

    //Also worth noting, if I throw new RuntimeException("Aww Noos"); here then it won't take it from the queue, but it won't get consumed (or end up as dead letter)...
}
like image 473
Scotty OB Avatar asked Feb 01 '12 12:02

Scotty OB


People also ask

How do I acknowledge a JMS message?

The application can acknowledge the receipt of each message individually, or it can receive a batch of messages and call the Acknowledge method only for the last message it receives. When the Acknowledge method is called all messages received since the last time the method was called are acknowledged.

How do I send a message to JMS listener?

Using @JmsListener and @SendTo The @SendTo annotation specifies a destination and indicates that method's return value should be converted to a Message and sent to the specified destination. The @SendTo annotation is used at method level with @JmsListener .


1 Answers

Read this documentation: Spring JMS container does not use the message.acknowledge()

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.

like image 184
Tarun Avatar answered Sep 30 '22 08:09

Tarun