ActiveMQ报错:Cannot synchronously receive a message when a MessageListener is set

本文介绍了在使用ActiveMQ时遇到的错误:不能在已设置MessageListener的情况下同步接收消息。作者分析了问题,指出在消费者类中同时使用了两种接收消息的方法,导致错误。解决方案是只需保留一种消息接收方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ActiveMQ报错:Cannot synchronously receive a message when a MessageListener is set


最近在看消息队列,看了ActiveMQ的消息队列,我自己模拟消息生产者与消息消费者,不过期间一直遇到了这个问题,网上查找了好久,终于找到了解决方案,自己写的有问题。

消息生产者代码

  • 生产者

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class ProducerTool {

    private String user = ActiveMQConnection.DEFAULT_USER;
    private String password = ActiveMQConnection.DEFAULT_PASSWORD;
    private String url = ActiveMQConnection.DEFAULT_BROKER_URL;
    private String subject = "xiaojian";
    private Destination destination = null;
    private Connection connection = null;
    private Session session = null;
    private MessageProducer producer = null;

    //初始化
    private void initialize() throws JMSException {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user, password, url);
        connection = connectionFactory.createConnection();
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = session.createQueue(subject);
        producer = session.createProducer(destination);
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
    }

    //发消息
    public void produceMessage(String message) throws JMSException {
        initialize();
        TextMessage msg = session.createTextMessage(message);
        connection.start();
        System.out.println("Producer: -> Sending message : " + message);
        producer.send(msg);
        System.out.println("Producer: -> Message sent complete !");
    }

    //关闭连接
    public void close() throws JMSException {
        System.out.println("Producer: -> Closing connection");
        if (null != producer) {
            producer.close();
        }
        if (null != session) {
            session.close();
        }
        if (null != connection) {
            connection.close();
        }
    }
}
  • 生产者启动代码

import javax.jms.JMSException;
import java.util.Random;

public class ProducerTest {

    public static void main(String[] args) throws JMSException {

        ProducerTool producerTool = new ProducerTool();
        Random random = new Random();

        for (int i = 0; i < 20; i++) {
            try {
                int sleep = random.nextInt(10) * 1000;
                System.out.println(sleep);
                Thread.sleep(sleep);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            producerTool.produceMessage("Hello , world ! -- " + i);
            producerTool.close();
        }

    }
}

消息消费者代码

  • 消费者

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class ConsumerTool implements MessageListener,ExceptionListener {

    private String user = ActiveMQConnection.DEFAULT_USER;
    private String password = ActiveMQConnection.DEFAULT_PASSWORD;
    private String url = ActiveMQConnection.DEFAULT_BROKER_URL;

    private String subject = "xiaojian";
    private Destination destination = null;
    private Connection connection = null;
    private Session session = null;
    private MessageConsumer consumer = null;
    private ActiveMQConnectionFactory connectionFactory = null;
    public static Boolean isConnection = false;


    //初始化
    private void initialize() throws JMSException {
        connectionFactory = new ActiveMQConnectionFactory(user,password,url);
        connection = connectionFactory.createConnection();
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = session.createQueue(subject);
        consumer = session.createConsumer(destination);
    }

    //消费消息
    public void consumeMessage() throws JMSException {
        initialize();
        connection.start();

        consumer.setMessageListener(this);
        connection.setExceptionListener(this);
        System.out.println("Consumer: -> Begin listening ...");
        isConnection = true;
        //开始监听
        Message receive = consumer.receive();
        System.out.println(receive.getJMSMessageID());
    }

    //关闭连接
    public void close() throws JMSException {
        System.out.println("Consumer: -> Closing connection ");
        if (null != consumer) {
            consumer.close();
        }
        if (null != session) {
            session.close();
        }
        if (null != connection) {
            connection.close();
        }
    }


    @Override
    public void onException(JMSException exception) {
        isConnection = false;
    }

    //消息处理函数
    @Override
    public void onMessage(Message message) {
        try {
            if (message instanceof TextMessage) {
                TextMessage textMessage = (TextMessage) message;
                String msg = textMessage.getText();
                System.out.println("Consumer: -> Received: " + msg);
            } else {
                System.out.println("Consumer: -> Received: " + message);
            }
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}
  • 生产者启动代码

import javax.jms.JMSException;

public class ConsumerTest implements Runnable{

    static Thread t1 = null;

    public static void main(String[] args) throws InterruptedException {
        t1 = new Thread(new ConsumerTest());
        t1.start();
        while (true) {
            System.out.println(t1.isAlive());
            if (!t1.isAlive()) {
                t1 = new Thread(new ConsumerTest());
                t1.start();
                System.out.println("重新启动了");
            }
            Thread.sleep(5000);
        }
        //延时 5000 毫秒之后停止接受信息;
    }

    @Override
    public void run() {
        try {
            ConsumerTool consumerTool = new ConsumerTool();
            consumerTool.consumeMessage();
            while (ConsumerTool.isConnection) {
//                System.out.println(123);
            }
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

遇到的问题

javax.jms.IllegalStateException: Cannot synchronously receive a message when a MessageListener is set
	at org.apache.activemq.ActiveMQSession.checkMessageListener(ActiveMQSession.java:2002)
	at org.apache.activemq.ActiveMQMessageConsumer.checkMessageListener(ActiveMQMessageConsumer.java:836)
	at org.apache.activemq.ActiveMQMessageConsumer.receive(ActiveMQMessageConsumer.java:519)
	at com.xiaojian.mq.ConsumerTool.consumeMessage(ConsumerTool.java:42)
	at com.xiaojian.mq.ConsumerTest.run(ConsumerTest.java:28)
	at java.lang.Thread.run(Thread.java:748)

后来,经过我网上搜寻,才发现我犯了一个很无知的错误。

问题分析解决


    //消费消息
    public void consumeMessage() throws JMSException {
        initialize();
        connection.start();

        consumer.setMessageListener(this);
        connection.setExceptionListener(this);
        System.out.println("Consumer: -> Begin listening ...");
        isConnection = true;
        //开始监听
        Message receive = consumer.receive();
        System.out.println(receive.getJMSMessageID());
    }

这个是我的消息消费者的一个方法,该方法中我先使用了consumer.setMessageListener(this),之后我又Message receive = consumer.receive();。这两个都是接受消息的方法,但是我两者都使用了,所以上面的那个setMessageListener就会报错,此处两者取一就可。

上面的消息消费者类,我实现了两个接口,所以在

consumer.setMessageListener(this);
connection.setExceptionListener(this);

可以使用this代替这个消费者类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值