Spring DefaultMessageListenerContainer - listener

2019-06-25 13:23发布

问题:

I am using Spring 3.0 - DefaultMessageListenerContainer to connect to a Websphere 6 MQ. There are some messages already present on the MQ. When I run my test, the listener implementing SessionAwareMessageListener is started. But the onMessage() does not get invoked. So the problem is that the messages already in the queue are not read.

As per the docs, autoStartup is true by default (and I have not changed this). As per my underatanding, On startup, the listener should read the Queue for any existing messages and onMessage() should get invoked. Please let me know if this understanding is wrong.

Here is the snippet from the config file:

    <bean id="jmsContainer"
        class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="jmsQueueConnectionFactory" />
        <property name="destinationName">
            <value>${queue}</value>
        </property>
        <property name="messageListener" ref="exampleMessageListener" />
        <property name="concurrentConsumers" value="1" />
        <property name="maxConcurrentConsumers" value="1" />
        <property name="idleTaskExecutionLimit" value="4" />
        <property name="maxMessagesPerTask" value="4" />
        <property name="receiveTimeout" value="5000" />
        <property name="recoveryInterval" value="5000" />
        <property name="sessionTransacted" value="true" />
        <property name="transactionManager" ref="jmsTransActionManager" />
    </bean> 

Note: There is no error/exception, the test app starts up just fine.

Any pointers to resolve this will be of great help.

Thanks,
RJ

回答1:

The issue is resolved. The test class was terminating after the listener got hold of the message but before it could show the message as output. So the first message (highest priority one) was getting lost from the queue.

Later as I had included a Transaction Manager, the listener was putting the message back on the queue (showing a warning as Rejecting received message because of the listener container having been stopped in the meantime). As this was a warning and my logger was at a Debug level, I missed this earlier.

Putting a thread.sleep in the test class made sure that it is running for a longer time and the listener could read all the messages in the queue in the order of priority :)

cheers,
RJ



回答2:

This, is not an answer in fact, but I do not want to create new question for very same problem.

I initialized the Spring context

ctx = new ClassPathXmlApplicationContext("classpath:" + args[0]);

read the configuration and then called (because of warning that reasource was not closed):

ctx.stop();

and I didn't realize that it will stop my beans, after one day of debugging I found this message in log

DEBUG o.s.c.s.DefaultLifecycleProcessor - Asking bean 'messageListenerContainer' of type [class org.springframework.jms.listener.DefaultMessageListenerContainer] to stop