Java JMS-消息侦听器和onException

问题描述 投票:0回答:1

我有一个带有主线程和JMS线程的应用程序,它们通过ActiveMQ 5.15.11相互通信。我能够很好地发送消息,但是我想要一种发回状态或错误的方法。我注意到MessageListener允许onSuccess()onException(ex)作为两个事件来监听,但是我发现只有onSuccess()被调用。

以下是我的代码段。

[JMS线程:

ConnectionFactory factory = super.getConnectionFactory();
Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(super.getQueue());
MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(m -> {
   try {
      super.processRmbnConfigMsg(m);
   } catch (JMSException | IOException e) {
      LOG.error(e.getMessage(), e);

      // I can only use RuntimeException. 
      // Also this exception is what I am expecting to get passed to the onException(..)
      // call in the main thread.
      throw new RuntimeException(e);
   }
});
connection.start();

主线程(将消息发送到JMS):

sendMessage(xml, new AsyncCallback() {
    @Override
    public void onException(JMSException e) {
        // I am expecting this to be that RuntimeException from the JMS thread.
        LOG.error("Error", e);
        doSomethingWithException(e);
    }

    @Override
    public void onSuccess() {
        LOG.info("Success");
    }
});

我期望的是,即使包装了new RuntimeException(e),也会以某种方式在onException(JMSException e)事件侦听器中拾取在RuntimeException中引发的异常。

相反,我总是收到onSuccess()事件。我想onException(..)事件是在通信问题期间发生的,但是我想要一种发送回调用方异常的方法。

我如何实现在JMS线程中收集错误并将其发送回我的调用线程的目标?

java jms activemq
1个回答
2
投票

您的期望基于对JMS的基本误解。

代理消息传递的基本原则之一是,生产者和消费者在逻辑上是彼此断开的。换句话说...生产者向代理发送消息,它不一定在乎消息是否被成功使用,并且肯定不知道会使用它或何时有任何保证。被消耗。同样,消费者不一定知道何时,为什么发送消息或由谁发送消息。这在生产者和消费者之间提供了极大的灵活性。 JMS坚持生产者和消费者之间没有联系的原则。 没有任何

直接

方式,消费者可以将其发送的消息的使用问题通知生产者。就是说,您可以采用所谓的“请求/响应模式”,以便消费者可以向生产者提供某种反馈。您可以找到此模式的解释以及示例代码here此外,您正在使用的AsyncCallback类也不属于JMS。我相信它是org.apache.activemq.AsyncCallback由ActiveMQ本身专门提供,并且它仅为实际send操作的成功或失败提供回调(即,不用于消息的消耗)。

最后,您应该知道,从org.apache.activemq.AsyncCallbackRuntimeException方法中抛出onMessage被JMS规范视为“编程错误”,应避免。 JMS 2规范的8.7节规定:

听众有可能抛出javax.jms.MessageListener;但是,这被认为是客户端编程错误。行为良好的侦听器应捕获此类异常,并尝试将导致它们定向到某种形式的特定于应用程序的“不可处理的消息”目的地的消息转移。侦听器抛出RuntimeException的结果取决于会话的确认模式。

    RuntimeExceptionAUTO_ACKNOWLEDGE-消息将立即重新发送。 JMS提供者在放弃之前重新传递相同消息的次数取决于提供者。对于在这种情况下重新传递的消息,将设置JMSRedelivered消息头字段,并增加JMSXDeliveryCount消息属性。

  • DUPS_OK_ACKNOWLEDGE-传递给侦听器的下一条消息。如果客户端希望重新传递之前的未确认消息,则必须手动恢复会话。

  • Transacted Session-传递给侦听器的下一条消息。客户端可以提交或回滚会话(换句话说,CLIENT_ACKNOWLEDGE不会自动回滚会话)。

  • © www.soinside.com 2019 - 2024. All rights reserved.