8

So question is how to temporary stop and start a jms listener created using spring using the fallowing way :

<amq:connectionFactory id="exampleJmsFactory" brokerURL="tcp://${jms.broker.url}" />

<jms:listener-container concurrency="1" connection-factory="exampleJmsFactory"  destination-type="queue" message-converter="exampleMessageConverter">
        <jms:listener destination="incoming.example.client.queue" ref="exampleProductsMessageConsumer" method="consume"/>
</jms:listener-container>


<bean id="exampleProductsMessageConsumer" class="com.unic.example.jms.receive.JmsExampleProductsMessageConsumer" scope="tenant"/>

So basically what is the problem. We do have an init/update mechanism that the client can run in any time and durring this init/update I want to stop consuming of ANY messages because the system is unusable in this time and if a message came it will be lost.

So how I can stop the listener or the listener container or the whole connection using the API. I found that a class AbstractJmsListeningContainer have stop/start but how I can get it ? I mean none of this jms: listener and listener-containers have a name or anything like that.

jNayden
  • 1,592
  • 2
  • 17
  • 29

3 Answers3

11

You can assign an id to the listener-container. Then get a reference to it, either by calling getBean or getting it injected. This will give you a AbstractJmsListeningContainer on which you can call start / stop.

gkamal
  • 20,777
  • 4
  • 60
  • 57
  • well first of all I cannot assign id really to the listener-container. The second issue is that in fact I have 3 listeners not just one so it is 1 listener-container with 3 listeners so if I try to get by class DefaultMessageListenerContainer or AbstractJmsListeningContainer it tells me that it finds 3. I guess for each listener it creates a listener container so I cannot really lookup by class/type – jNayden Jul 10 '12 at 07:32
  • ahh the listener object itself have an id which is passed to the container let me try that – jNayden Jul 10 '12 at 07:57
6

Yes thats do the trick.

<jms:listener-container concurrency="1" connection-factory="exampleJmsFactory"  destination-type="queue" message-converter="exampleMessageConverter">
        <jms:listener id="exampleProductsMessageListener" destination="incoming.example.client.queue" ref="exampleProductsMessageConsumer" method="consume"/>
</jms:listener-container>



DefaultMessageListenerContainer exampleProductsMessageListener= Registry.getApplicationContext().getBean("exampleProductsMessageListener", DefaultMessageListenerContainer.class);
exampleProductsMessageListener.stop();
giannis christofakis
  • 8,201
  • 4
  • 54
  • 65
jNayden
  • 1,592
  • 2
  • 17
  • 29
  • How ill do it when i have 10 listeners, calling the same consume method. First i have to identify which listener is calling my consume method. this will make this code cumbersome. Do you any other suggestion for the same objective. – vashishth Jul 29 '14 at 11:22
  • @JOKe When I `stop()` my listener, the `isRunning()` return False, but I still get messages through the MQueue... Any idea ? – Radhwen Apr 04 '17 at 12:40
1

You can also get a hold of the messageListenerContainer, and invoke stop() on it:

@javax.annotation.Resource //autowire by name
 private AbstractJmsListeningContainer myMessageListenerContainer;

 myMessageListenerContainer.stop();

 I'm using the more verbose setup of this container:
 <bean id="myMessageListenerContainer" class="org.springframework.jms.listener.DefaultMes sageListenerContainer">
 <property name="connectionFactory" ref="jmsConnectionFactory"/>
 <property name="destination" ref="myQueue"/>
 <property name="messageListener" ref="myListener"/>
 <property name="autoStartup" value="true" />
 </bean>

Here you see that you can set autoStartup to false if you don't want the listenerContainer to automatically start.