Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper setup for spring defaultmessagelistener container on glassfish for redelivery after exception?

I'm trying to setup spring's DefaultMessageListenerContainer class to redeliver messages after an exception is thrown or session.rollback() is called. I am also trying to get this running on glassfish 3.1.2 web profile.

When calling session.rollback() in the onMessage() method of my SessionAwareMessageListener, I get an exception with the message saying: MessageDispatcher - [C4024]: The session is not transacted. I don't see this problem with ActiveMQ, but of course that configuration is different because I'm not using it in an application server.

Has anyone here gotten this working? My configuration follows:

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">com.sun.enterprise.naming.SerialInitContextFactory</prop>
            <prop key="java.naming.provider.url">${jms.jndicontext.url}</prop>
            <prop key="java.naming.factory.state">com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl</prop>
            <prop key="java.naming.factory.url.pkgs">com.sun.enterprise.naming</prop>
        </props>
    </property>
</bean>

<bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate" ref="jndiTemplate" />
    <property name="jndiName" value="${jms.connection.factory}" />
</bean>

<bean id="jmsTemplate"
      class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
    <property name="defaultDestination" ref="jmsServiceQueue"/>
</bean>

<bean id="jmsServiceProducer"
      class="net.exchangesolutions.services.messaging.service.jms.JmsMessageServiceProducerImpl">
    <property name="serviceTemplate" ref="jmsTemplate"/>
    <property name="serviceDestination" ref="jmsServiceQueue"/>
</bean>

<bean id="myMessageListener"
      class="com.myorg.jms.MessageDispatcher"/>


<bean id="jmsServiceContainer"
   class="org.springframework.jms.listener.DefaultMessageListenerContainer">
   <property name="connectionFactory" ref="jmsConnectionFactory"/>
   <property name="destination" ref="jmsServiceQueue"/>
   <property name="messageListener" ref="myMessageListener"/>
   <property name="errorHandler" ref="jmsErrorHandler" />
   <property name="receiveTimeout" value="180000"/>
   <property name="concurrentConsumers" value="1"/>
   <property name="cacheLevelName" value="CACHE_NONE"/>
   <property name="pubSubNoLocal" value="true"/>
   <property name="sessionTransacted" value="true"/>
   <property name="sessionAcknowledgeMode" value="2" />
   <property name="transactionManager" ref="jmsTransactionManager"/>
</bean>

<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
</bean>
like image 778
user1717499 Avatar asked Dec 06 '25 01:12

user1717499


1 Answers

Setting the acknowledge="auto", the message is acknowledged before listener execution, so the message is deleted from queue.

I have also achieved the DLQ scenario in Spring Application by doing the following changes to your code.

First, we set the acknowledge="transacted" (Since we want guaranteed redelivery in case of exception thrown and Trans acknowledgment for successful listener execution)

<jms:listener-container container-type="default" connection-factory="connectionFactory" acknowledge=" transacted">

Next, since we want to throw the JMSException, we are implementing SessionAwareMessageListener.

public class MyMessageQueueListener implements SessionAwareMessageListener {
    public void onMessage( Message message , Session session ) throws JMSException {
        //DO something
        if(success){
            //Do nothing – so the transaction acknowledged
        } else {
            //throw exception - So it redelivers
            throw new JMSException("..exception");
        } 
    }
}

I have tested this. This seems working fine.

like image 147
monu Avatar answered Dec 10 '25 10:12

monu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!