【问题标题】:JMS Not consuming message after setting up temporary queue设置临时队列后 JMS 不使用消息
【发布时间】:2013-10-07 16:47:03
【问题描述】:

我设置了一个简单的请求/回复类型场景(JavaEE 7/Netbeans 7 with Glassfish),代码如下:

这是一个执行 JMS 生产者角色的无状态会话 bean
destinationfactory 被注入到 EJB 中。

public void doStuff(int id) {

    try {
    Connection connection = factory.createConnection();
    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    MessageProducer producer = session.createProducer(destination);
    ObjectMessage message = session.createObjectMessage();

    MyObject obj = new MyObject(id);
    connection.start();

    TemporaryQueue replyQueue = session.createTemporaryQueue();
    MessageConsumer consumer = session.createConsumer(replyQueue);

    message.setJMSReplyTo(replyQueue);
    message.setObject(obj);

    producer.send(message, DeliveryMode.PERSISTENT, Message.DEFAULT_PRIORITY, 1800000);
    Message reply = consumer.receive();

    producer.close();
    session.close();
    connection.close();
    } catch (JMSException ex) {

    }
    }

我的问题是,当调用 consumer.receive() 时,执行会按预期阻塞 - 但是此消息的使用者永远不会运行。原始消息的使用者(它是一个 MDB)位于部署在同一 Glassfish 服务器上的另一个 netbeans 项目中。

我已经尝试调试两个项目(生产者和消费者),似乎当我的生产者项目阻塞时,我的消费者项目根本没有做任何事情。

如果我将consumer.recieve() 更改为consumer.receive(20000) 之类的东西,那么正如预期的那样,在 20 秒内什么也没有发生 - 但是一旦超时突然到期,我的消费者项目上就会出现一个调试器断点,它会正常处理.但是当然没有回复发送回我的生产者项目,因为它不再监听了!

我的另一个项目(消费者项目)看起来像这样:

@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/myQueue")
})
---------------------
    @Override
public void onMessage(Message message) {
    try {
        ObjectMessage objMessage = (ObjectMessage) message;
        MyObject obj = (MyObject) objMessage.getObject();
        Connection connection = factory.createConnection();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageProducer producer = session.createProducer(message.getJMSReplyTo());
        connection.start();

        try {
            myMethod(obj);
        } catch (Exception e) {

            Message response = session.createTextMessage(e.getMessage());
            producer.send(message.getJMSReplyTo(), response);
        }


    } catch (JMSException ex) {

    }
}

如何让 receive() 方法正常工作?我需要它暂停以等待回复,但在暂停时我需要我的另一个项目继续工作 - 如果它们是两个单独部署的项目,我会假设它们无论如何都在不同的线程上。

【问题讨论】:

    标签: java jakarta-ee netbeans glassfish jms


    【解决方案1】:

    我最终发现我遇到了这个问题,因为我的 doStuff() 方法正在运行一个容器管理事务。

    除此之外,每笔交易只能执行一项操作(例如:请求/接收中只有一项)

    所以当我调用producer.send() 时,消息实际上并没有发送,因为事务还没有完成(方法没有完成)。然后它继续拨打receive 电话并被阻止,因为没有发送任何消息。

    我通过使我的 doStuff() 方法成为 Bean Managed Transaction 来解决这个问题,我在 bean 上注入了一个带有 @Resource 注释的 UserTransaction 对象。

    我通过UserTransaction.beginUserTransaction.commit 绑定了发送操作,并重复此操作以绑定我的第二个接收操作 - 它按预期工作。

    这为我提供了关于 CMT 的清晰解释:http://docs.oracle.com/cd/E19798-01/821-1841/bncij/index.html

    【讨论】:

      猜你喜欢
      • 2012-01-03
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 2012-01-19
      • 1970-01-01
      • 1970-01-01
      • 2020-04-05
      • 1970-01-01
      相关资源
      最近更新 更多