【发布时间】: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