verbose-mode verbose-mode - 4 months ago 35
Java Question

JAX-WS: Connection won't close - stops messaging after x messages

I've got a little problem with JAX-WS. I'm using ActiveMQ as MOM and Spring.
The messaging is really simple: one jar should send a soap message with some data to another.
I defined the client this way in my sender_beans.xml







<bean id="jmsConfig-Manager" class="org.apache.cxf.transport.jms.JMSConfiguration"
p:connectionFactory-ref="jmsConnectionFactory"
p:targetDestination="activemq:example.manager"
p:pubSubDomain="true" p:maxConcurrentConsumers="40" p:deliveryMode="1"
p:explicitQosEnabled="true" p:reconnectOnException="true" />

<bean id="jmsConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="sessionCacheSize" value="40" />

<property name="targetConnectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL"

value="tcp://localhost:61616?jms.useAsyncSend=true" />
</bean>
</property>
</bean>


And this is my endpoint:

<jaxws:endpoint id="ManagerService" implementor="#ManagerServ"
implementorClass="com.example.Service"
address="jms://">
<jaxws:features>
<bean class="org.apache.cxf.transport.jms.JMSConfigFeature"
p:jmsConfig-ref="jmsConfig-Manager" />
</jaxws:features>
</jaxws:endpoint>
<bean id="jmsConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="sessionCacheSize" value="40" />

<property name="targetConnectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL"

value="tcp://localhost:61616?jms.useAsyncSend=true" />
</bean>
</property>
</bean>


So, the messaging works - but only 40 times! (Which is the value of ever p:maxConcurrentConsumers). I think the problem is that everytime a message is send, a new consumer is created but never destroyed. So after 40 messages no new consumer can be created and the messaging stops working. I have to restart the complete messaging.
I only can use the declarative way to fix this problem, I never call anything from jms in my code.
Has anybody a solution? This is really urgent, I hope somebody can help me :-)

Answer

The CachingConnectionFactory by default will cache message consumers and producers. You can disable this by setting the cacheConsumers and cacheProducers properties to 'false'.

I.e. for your Spring xml:

<bean id="jmsConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
   <property name="sessionCacheSize" value="40" />
   <property name="cacheConsumers" value="false" />
   <property name="targetConnectionFactory">
...

I had a recent issue where programmatically created Message Consumers weren't being destroyed when calling .close() on the consumer object (I could still see the active consumers on the ActiveMQ admin console). cacheConsumers = false resolved this for me.

Furthermore, read the Spring API on the Caching and Single connection factories to ensure you are using the correct one for your scenario - they mention all of this.