Spring JMS Listener Container stop only half of li

2019-08-28 14:09发布

I have weired problem with a JMS Listener container. In case I disable the listener container, half of messages are delivered 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.

1条回答
欢心
2楼-- · 2019-08-28 14:49

My guess is that you are loading the container into both the web context (DispatcherServlet's context) and the root context (ContextLoaderListener's context). Which means you have 2 containers and you are only stopping the one in the servlet context.

Turn on DEBUG logging for org.springframework and examine the bean initialization logs.

It probably should be just in the root context.

查看更多
登录 后发表回答