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
代替这个消费者类