On the suggestion of using the jmsGateway xml setup it does not appear to be calling start or initialize, (tried setting breakpoints) therefore its never subscribing to the JMS queue.
So I attempted just to create it as a bean as follows.
Code:
<beans:bean id="jmsGateWay" class="org.springframework.integration.adapter.jms.JmsGateway" init-method="start" destroy-method="destroy">
<beans:property name="connectionFactory" ref="connectionFactory"/>
<beans:property name="requestChannel" ref="channel"/>
<beans:property name="destination" ref="queue"/>
<beans:property name="expectReply" value="false"/>
<beans:property name="sessionTransacted" value="true"/>
</beans:bean>
This causes me to get an exception
Code:
DefaultMessageListenerContainer-2 DefaultMessageListenerContainer INFO - Setup of JMS message listener invoker failed - trying to recover
javax.jms.JMSException: JTA transaction required for JtaMessageConsumer
at com.atomikos.jms.DefaultJtaMessageConsumer.enlist(Unknown Source)
at com.atomikos.jms.DefaultJtaMessageConsumer.receive(Unknown Source)
at com.atomikos.jms.DefaultJtaMessageConsumer.receive(Unknown Source)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:404)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:307)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:260)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:944)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:868)
at java.lang.Thread.run(Thread.java:613)
This is caused by DefaultMessageListenerContainer / AbstractPollingMessageListenerContainer not having a reference to the transactionManager and there being no way to pass the transactionManager through the jmsGateway (since jmsGateway by default creates an instance of DefaultMessageListenerContainer) and jmsGateway does not have a transactionManager property.
Therefore I finally change the code to this.
Code:
<beans:bean id="jmsGateWay" class="org.springframework.integration.adapter.jms.JmsGateway" init-method="start" destroy-method="destroy">
<beans:property name="connectionFactory" ref="connectionFactory"/>
<beans:property name="requestChannel" ref="channel"/>
<beans:property name="destination" ref="queue"/>
<beans:property name="expectReply" value="false"/>
<beans:property name="sessionTransacted" value="true"/>
<beans:property name="container" ref="messageListenerContainer"/>
</beans:bean>
<beans:bean id="messageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<beans:property name="connectionFactory" ref="connectionFactory"/>
<beans:property name="destination" ref="queue"/>
<beans:property name="transactionManager" ref="transactionManager"/>
<beans:property name="sessionTransacted" value="true"/>
</beans:bean>
and my test finally passes.
So two suggestions.
- Make sure jmsGateway calls setup and destroy methods (as needed), or prove me wrong - I could have easily screwed up my configuration.
- Add the transactionManager property to jmsGateway (xml schema and object) and pass it through to the DefaultMessageListenerContainer.
This has been posted jira as INT-237
Thanks,
Chris