Search code examples
spring-bootspring-jmsjmstemplate

JMS Template close the connection before acknowledgement


The application use JMS template to connect MQ. Post consumer read the message when it goes to acknowledge the error thrown below.

com.ibm.msg.client.jms.DetailedIllegalStateException: JMSCC0020: This session is closed. An application called a method that must not be used after the session is closed. Ensure that the session is not closed before calling the method.

JMS Template Spring bean XML

<beans>
    <bean id="mqDestinationResolver"
          class="org.springframework.jms.support.destination.DynamicDestinationResolver">
    </bean>
    <bean id="QUEUE_CONNECTION_FACTORY" class="com.ibm.mq.jms.MQConnectionFactory" >
        <property name="transportType" value="1" />
        <property name="queueManager" value="QM.XXX" />
        <property name="hostName" value="XXX.com" />
        <property name="port" value="XXX" />
        <property name="channel" value="XXX" />
        <property name="SSLCipherSuite" value="XXX" />
    </bean>
    <bean id="destination" class="com.ibm.mq.jms.MQQueue">
        <constructor-arg value="INTERQUEUE" />
    </bean>
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="QUEUE_CONNECTION_FACTORY" />
        <property name="destinationResolver" ref="mqDestinationResolver"/>
        <property name="defaultDestination">
            <ref bean="destination" />
        </property>
        <property name="pubSubDomain" value="false"/>
        <property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE"/>
    </bean>
    <bean id="messageConsumer" class="com.jms.JmsMessageConsumer">
        <property name="jmsTemplate" ref="jmsTemplate"/>
    </bean>
</beans>

The JMS Consumer class.

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import org.springframework.jms.core.JmsTemplate;

public class JmsMessageConsumer {

private JmsTemplate jmsTemplate;

public JmsTemplate getJmsTemplate() {
    return jmsTemplate;
}

public void setJmsTemplate(JmsTemplate jmsTemplate) {
    this.jmsTemplate = jmsTemplate;
}

public Message receiveMessage() throws JMSException {
    System.out.println("Start  : Inside JMS message Consumer");
    Message msg =(Message)getJmsTemplate().receive();
    msg.acknowledge();
    System.out.println("End  : Inside JMS message Consumer");
    return msg;
}}

Solution

  • The session is already closed when the receive() exits. With CLIENT_ACKNOWLEDGE, the template automatically acks the message before exiting.