Lipo
Lipo

Reputation: 75

How to stop and start jms listener

I'm using Spring and I have a JMS queue to send messages from client to server. I'd like to stop the messages from being sent when the server is down, and resend them when it's back up.

I know it was asked before but I can't make it work. I created a JmsListener and gave it an ID, but I cannot get it's container in order to stop\start it.

@Resource(name="testId")
private AbstractJmsListeningContainer _probeUpdatesListenerContainer;

public void testSendJms() {

    _jmsTemplate.convertAndSend("queue", "working");
}

@JmsListener(destination="queue", id="testId")
public void testJms(String s) {
    System.out.println("Received JMS: " + s);

}

The container bean is never created. I also tried getting it from the context or using @Autowired and @Qualifier("testId") with no luck.

How can I get the container?

Upvotes: 2

Views: 9917

Answers (3)

James Parson
James Parson

Reputation: 63

I used JmsListenerEndpointRegistry. Here's my example. I hope this will help.

Bean configuration in JmsConfiguration.java. I changed default autostart option.

@Bean(name="someQueueScheduled")
public DefaultJmsListenerContainerFactory odsContractScheduledQueueContainerFactory() {
   DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
   ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(someActiveMQ);
   Map<String, Class<?>> typeIds = new HashMap<>();
   typeIds.put(SomeDTO);
   factory.setMessageConverter(messageConverter(Collections.unmodifiableMap(typeIds)));
    factory.setPubSubDomain(false);
    factory.setConnectionFactory(cf);
    factory.setAutoStartup(false);
    return factory;
}

Invoke in SomeFacade.java

public class SomeFacade {

@Autowired
JmsListenerEndpointRegistry someUpdateListener;

public void stopSomeUpdateListener() {
  MessageListenerContainer container = someUpdateListener.getListenerContainer("someUpdateListener");
  container.stop();
  }


public void startSomeUpdateListener() {
  MessageListenerContainer container = someUpdateListener.getListenerContainer("someUpdateListener");
  container.start();
  }
}

JmsListener implementation in SomeService.java

public class SomeService {

 @JmsListener(id = "someUpdateListener",
      destination = "${some.someQueueName}",
      containerFactory ="someQueueScheduled")
  public void pullUpdateSomething(SomeDTO someDTO)  {
  }
}

Upvotes: 1

Justin Qiu
Justin Qiu

Reputation: 21

If you use CachingConnectionFactory in your project, you need to call the resetConnection() method between stop and restart, otherwise the old physical connection will remain open, and it will be reused when you restart.

Upvotes: 1

Gary Russell
Gary Russell

Reputation: 174769

You need @EnableJms on one of your configuration classes.

You need a jmsListenerContainerFactory bean.

You can stop and start the containers using the JmsListenerEndpointRegistry bean.

See the Spring documentation.

Upvotes: 1

Related Questions