【问题标题】:JMS Temporary Queue - Replies not returning back to clientJMS 临时队列 - 回复未返回给客户端
【发布时间】:2026-01-18 22:15:02
【问题描述】:

我正在尝试从 Weblogic 迁移到 JBoss,因此我正在尝试在 JBoss 上实现我能够在 Weblogic 上实现的东西。

其中之一是我们的通知系统,其中客户端向 MDB 发送请求,然后 MDB 将回复发送回客户端。

这在 Weblogic 中是轻而易举的事,但在 Jboss 上似乎没有任何效果。我不断收到此错误:

javax.jms.InvalidDestinationException: Not an ActiveMQ Artemis Destination:ActiveMQTemporaryQueue[da00b1a2-114d-4be9-930d-926fc20c2fce]

我需要在我的 Jboss 上配置什么吗?

编辑

我意识到我可能没有很好地表达这个问题。

会发生什么:我有一个客户端和一个服务器 MDB(消息驱动 bean)。客户端将消息发送到队列并等待来自服务器的响应。服务器从队列中挑选消息并向客户端发送响应,客户端挑选并显示该响应。

在 Jboss 上,来自客户端的消息顺利进行,服务器会接收它,但是一旦服务器 MDB 尝试向客户端发送响应,就会抛出该错误。

我的客户代码(摘录):

int TIME_OUT = 60000;

            //prepare factory
            Properties prop = new Properties();
            prop.setProperty("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory");
            prop.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
            prop.setProperty("java.naming.provider.url", "http-remoting://remotehost:8080");
            prop.setProperty("java.naming.security.principal", "guest-user")
            prop.setProperty("java.naming.security.credentials", "Password@1")

            String queueConnectionFactory = "jms/RemoteConnectionFactory";

            Context context = new InitialContext(prop);
            QueueConnectionFactory qconFactory = (QueueConnectionFactory) context.lookup(queueConnectionFactory);

            //prepare queue and sessions
            QueueConnection qcon = qconFactory.createQueueConnection(prop.getProperty("java.naming.security.principal"), prop.getProperty("java.naming.security.credentials"));
            QueueSession qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            Queue queue = (Queue) context.lookup("jms/TestQueue2");

            //create message
            NotificationWrapper wrapper = //object initialised with something
            ObjectMessage om = qsession.createObjectMessage(wrapper);//NotificationWrapper wrapper

            //create producer
            MessageProducer producer = qsession.createProducer(queue);

            //create temporary queue
            TemporaryQueue tempqueue = qsession.createTemporaryQueue();
            om.setJMSReplyTo(tempqueue);

            //start connection
            qcon.start();

            //send message and wait for response
            producer.send(om);
            MessageConsumer consumer = qsession.createConsumer(tempqueue);
            Message callback = consumer.receive(TIME_OUT);

            //print message from server
            if (callback != null) {
                System.out.println("Response received from server. Print here...");
                //message from server
            } else {
                System.out.println("No Response received from server. Problems!!!");
            }

            //close all connections
            if (consumer != null) {
                consumer.close();
            }
            if (producer != null) {
                producer.close();
            }
            if (qsession != null) {
                qsession.close();
            }
            if (qcon != null) {
                qcon.close();
            }

我的服务器代码(摘录):

@MessageDriven(mappedName = "TestQueue2", activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "destination", propertyValue = "jms/TestQueue2"),
    @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10")
})
public class ServerSide implements MessageListener {
    private static final QueueConfigProperties queueConfigProp = QueueConfigProperties.getInstance();
    private Context context;
    private QueueConnectionFactory qconFactory;
    private QueueConnection qcon;
    private QueueSession qsession;
    private MessageProducer producer;

    public ServerSide() {
        try {
            initialiseQueueFactory("jms/RemoteConnectionFactory");
            //initialiseQueueFactory("jms/GreenpoleConnectionFactory");
            prepareResponseQueue();
            Properties prop = new Properties();
            prop.setProperty("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory");
            prop.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
            prop.setProperty("java.naming.provider.url", "http-remoting://remotehost:8080");
            prop.setProperty("java.naming.security.principal", "guest-user")
            prop.setProperty("java.naming.security.credentials", "Password@1")

            String queueConnectionFactory = "jms/RemoteConnectionFactory";

            Context context = new InitialContext(prop);
            QueueConnectionFactory qconFactory = (QueueConnectionFactory) context.lookup(queueConnectionFactory);

            qcon = qconFactory.createQueueConnection(queueConfigProp.getProperty("java.naming.security.principal"), queueConfigProp.getProperty("java.naming.security.credentials"));
            qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
        } catch (NamingException | ConfigNotFoundException | IOException | JMSException ex) {
            //error log
        }
    }

    @Override
    public void onMessage(Message message) {
        try {
            if (((ObjectMessage) message).getObject() instanceof NotificationWrapper) {
                //send response
                if (message.getJMSReplyTo() != null) {
                    logger.info("sending response");
                    respondToSenderPositive(message);

                    Response resp = new Response();
                    resp.setRetn(0);
                    resp.setDesc("Notification submitted to queue.");

                    producer = qsession.createProducer(message.getJMSReplyTo());
                    producer.send(qsession.createObjectMessage(resp));

                    producer.send(msg_to_send);
                }
            } else {
                //some message printed here
            }
        } catch (JMSException ex) {
            //error logs
        } catch (Exception ex) {
            //error logs
        }
    }
}

【问题讨论】:

  • 当目的地不被提供者理解或不再有效时必须抛出此异常。通常这意味着目的地的名称无效,例如传递给 Session.createQueue(String qName) 的参数仔细检查您的配置以确保您指定了正确的名称,很可能在某处有错误和/或您正在尝试与 ActiveMQ Artemis 不匹配的东西约定。
  • 本指南 access.redhat.com/documentation/en-us/… 解释了 JBoss EAP 7 中的 ActiveMQ Artemis 消息代理。
  • 嗨@AnupDey 感谢您的回复。在开始研究 Jboss 之前,我实际上阅读了整个文档。我已经编辑了我的问题,以便为我的解释提供更多内容。谢谢!

标签: jms jboss-eap-7


【解决方案1】:

问题与远程队列的目标队列的配置有关:客户端和服务器都在不同的 JVM 上运行。 Jboss 上的远程队列的命名与 Weblogic 上的不同。

远程队列的名称应该是这样的:java:jboss/exported/jms/TestQueue2

有关队列的更详细说明,请参阅 JBoss 文档:https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.0/html-single/configuring_messaging/index

【讨论】:

    最近更新 更多