2 Replies Latest reply on Mar 17, 2015 2:15 AM by roshen.po

    Spring JMS Listener Container stops only half of listeners

    boris.suska

      Hi,

       

      I have weird problem with a JMS Listener container. In case I stop the listener container, half of messages are still delivered to the app and processed by listener. Here is my Spring configuration:

       

      <bean id="ConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
          <property name="jndiName" value="JmsXA" />
      </bean>
      
      <bean id="testQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
          <property name="jndiName" value="queue/test" />
      </bean>
      
      <bean id="listener" class="eu.cuptech.jms.listener.ExampleListener" />
      
      <bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
          <property name="connectionFactory" ref="ConnectionFactory" />
          <property name="destination" ref="testQueue" />
          <property name="messageListener" ref="listener" />
          <property name="concurrency" value="1" />
      </bean>
      

       

      *ExampleListener* is here:

      package eu.cuptech.jms.listener;
       
      import javax.jms.JMSException;
      import javax.jms.Message;
      import javax.jms.MessageListener;
      import javax.jms.TextMessage;
      
      public class ExampleListener implements MessageListener {
          public void onMessage(Message message) {
              try {
                  String msg = ((TextMessage) message).getText();
                  System.out.println("MESSAGE TEXT: " + msg);
              } catch (JMSException e) {
                  throw new RuntimeException(e);
              }
          }
      }
      

       

      Client is Spring MVC Controller with following methods:

      *send10Messages* method (common JMS client):

      @Resource(name="ConnectionFactory")
      private ConnectionFactory connectionFactory;
      
      @Resource(name="testQueue")
      private Queue testQueue;
      
      @RequestMapping(value="send10", method = RequestMethod.GET)
      public String send10Messages(ModelMap model, HttpSession session) throws Exception {
          sendTextMessages(10, "Test message: ");
          return "redirect:/info";
      }
      
      private void sendTextMessages(int count, final String prefix) throws Exception {
          Connection connection = null;
          Session session = null;
          MessageProducer messageProducer = null;
          try {
              connection = connectionFactory.createConnection();
              session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
              messageProducer = session.createProducer(testQueue);
              connection.start();
              TextMessage message = session.createTextMessage();
              int i = 0;
              while (i < count) {
                  message.setText(prefix + ++i);
                  messageProducer.send(message);
                  Thread.sleep(250);
                  System.out.println("Message " + prefix + i + " sent.");
              }
          } finally {
              try {
                  if (messageProducer != null)
                      messageProducer.close();
                  if (connection != null)
                      connection.close();
                  if (session != null)
                      session.close();
              } catch (JMSException e) {
                  e.printStackTrace();
              }
          }
      }
      

       

      *disableListener* method:

      @Resource(name="listenerContainer")
      private DefaultMessageListenerContainer listenerContainer;
       
      @RequestMapping(value="disableListener", method = RequestMethod.GET)
      public String disableListener(ModelMap model, HttpSession session) {
          listenerContainer.stop(new Runnable() {
              public void run() {
                  System.out.println("JMS Listener stopped.");
              }
          });
          return "redirect:/info";
      }
      

       

      *enableListener* method:

      @Resource(name="listenerContainer")
      private DefaultMessageListenerContainer listenerContainer;
      
      @RequestMapping(value="enableListener", method = RequestMethod.GET)
      public String enableListener(ModelMap model, HttpSession session) {
          listenerContainer.start();
          return "redirect:/info";
      }
      

       

      When I start server and send messages I got this log (It is OK):

      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 1
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 1 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 2
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 2 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 3
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 3 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 4
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 4 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 5
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 5 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 6
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 6 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 7
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 7 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 8
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 8 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 9
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 9 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 10
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 10 sent.
      

       

      When I disable the listener container and send messages again I got this:

      INFO [stdout] (listenerContainer-1) JMS Listener stopped.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 1
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 1 sent.
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 2 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 3
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 3 sent.
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 4 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 5
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 5 sent.
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 6 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 7
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 7 sent.
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 8 sent.
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 9
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 9 sent.
      INFO [stdout] (http-localhost/127.0.0.1:8080-1) Message Test message: 10 sent.
      

       

      When I enable the listener container again I got this:

      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 2
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 4
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 6
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 8
      INFO [stdout] (listenerContainer-1) MESSAGE TEXT: Test message: 10
      

       

      The problem is that every odd message is processed by listener even if listener is disabled. I expact that all messages will be delivered and processed by listener when I enable the listener container and no message will be processed when I disable it.

       

      I'm using Spring 3.2.4.RELEASE (I was trying 3.2.3.RELEASE too), HornetQ 2.3.0.Final as remote JMS Server and JBoss 7.3.1.Final as App server.

       

      Any suggestions why it should do this?

        • 1. Re: Spring JMS Listener Container stops only half of listeners
          boris.suska

          I found a problem. I used the same config file by {noformat}ContextLoaderListener{noformat} and {noformat}DispatcherServlet{noformat}. I've got this in my web.xml:

           

          <servlet>
                    <servlet-name>mvc-dispatcher</servlet-name>
                    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                    <load-on-startup>1</load-on-startup>
          </servlet>
          
          <servlet-mapping>
                    <servlet-name>mvc-dispatcher</servlet-name>
                    <url-pattern>/</url-pattern>
          </servlet-mapping>
          
          <context-param>
                    <param-name>contextConfigLocation</param-name>
                    <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
          </context-param>
          
          <listener>
                    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
          </listener>
          

           

          mvc-dispatcher-servlet.xml was used as root context and dispatcher servlet context.  I changed contextConfigLocation to:

           

          <context-param>
                    <param-name>contextConfigLocation</param-name>
                    <param-value>/WEB-INF/root-context.xml</param-value>
          </context-param>
          

           

          I've to split a configuration between mvc-dispatcher-servlet.xml and root-context.xml

          • 2. Re: Spring JMS Listener Container stops only half of listeners
            roshen.po

            Hi can you explain, what is the fix for this. Im a new bie and facing same issue