Tomcat 的 ActiveMQ JMS 连接错误
ActiveMQ JMS Connection Error with Tomcat
我目前是这样配置我的 Tomcat 的 context.xml
的:
<Resource name="jms/ConnectionFactory" auth="Container" type="org.apache.activemq.ActiveMQConnectionFactory" description="JMS Connection Factory" factory="org.apache.activemq.jndi.JNDIReferenceFactory" brokerURL="tcp://MY_LOCALHOST_URL:7270" brokerName="LocalActiveMQBroker" useEmbeddedBroker="false"/>
<Resource name="AppJms-HVDIVD17CA50359" auth="Container" type="org.apache.activemq.ActiveMQConnectionFactory" factory="org.apache.activemq.jndi.JNDIReferenceFactory" physicalName="APP.QUEUE" />
我有我的 activemq.xml
:
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="appjms" uri="tcp://MY_LOCALHOST_URL:7270?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
我在 Java 中启动 JMS 代码如下:
public void createMessageSubscriberJms(String host, int port, String jmsDestination) throws JMSException, UnknownHostException {
String hostname = InetAddress.getLocalHost().getCanonicalHostName();
String providerEndpoints = "tcp://" + hostname + ":" + port + "?wireFormat.maxInactivityDuration=7200000";
// Set the trusted packages/classes to move back and forth on the ActiveMQ JMS service.
ArrayList<String> trustedClasses = new ArrayList<String>();
trustedClasses.add("com.gtt.common.shared.GTCMessage");
// Obtain the factory
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
activeMQConnectionFactory.setBrokerURL(providerEndpoints);
// Add the trusted packages/classes to the ActiveMQ consumer.
//activeMQConnectionFactory.setTrustedPackages(trustedClasses);
activeMQConnectionFactory.setTrustAllPackages(true);
//Create the connection
setQueueConnection(activeMQConnectionFactory.createQueueConnection());
getQueueConnection().setClientID(this.getName());
// Make a session
setSession(getQueueConnection().createQueueSession(false, Session.AUTO_ACKNOWLEDGE));
getSession().createQueue(jmsDestination);
// Create the destination
Destination destination = getSession().createQueue(jmsDestination);
String selector = "JMSCorrelationID = '" + getActionRequest().getOriginId() + "_" + getActionRequest().getRequestId() + "'" ;
setConsumer(getSession().createConsumer(destination, selector));
getConsumer().setMessageListener(new DefaultMessageListener(this));
// Start ...
// We'll need a message store now
gtcMessages = new GTCMessageQueue<GTCMessage>();
getQueueConnection().start();
}
但是当我启动 Tomcat 并调用该方法时,出现以下错误:
Name [AppJms-HVDIVD17CA50359] is not bound in this Context. Unable to find [AppJms-HVDIVD17CA50359].
你能告诉我我做错了什么吗?当我使用旧版本的 Tomcat 和 ActiveMQ 时,我确信相同的配置有效。
目前我正在使用 Tomcat 9.0.45 和 ActiveMQ 5.16.1。
你对 AppJms-HVDIVD17CA50359
的定义对我来说有点奇怪:
<Resource name="AppJms-HVDIVD17CA50359" auth="Container" type="org.apache.activemq.ActiveMQConnectionFactory" factory="org.apache.activemq.jndi.JNDIReferenceFactory" physicalName="APP.QUEUE" />
看起来您正在定义 JMS 队列,因为 physicalName
属性是 APP.QUEUE
。但是,type
是 org.apache.activemq.ActiveMQConnectionFactory
,这是 JMS 连接工厂而不是队列的正确 type
。此外,org.apache.activemq.ActiveMQConnectionFactory
class 没有 physicalName
属性。我认为你应该在这里使用 org.apache.activemq.command.ActiveMQQueue
作为 type
,例如:
<Resource name="AppJms-HVDIVD17CA50359" auth="Container" type="org.apache.activemq.command.ActiveMQQueue" factory="org.apache.activemq.jndi.JNDIReferenceFactory" physicalName="APP.QUEUE" />
值得注意的是,您似乎没有在此代码中使用 AppJms-HVDIVD17CA50359
或 jms/ConnectionFactory
。我没有看到任何使用这些名称的 JNDI 查找。因此,您可以简单地从 context.xml
中删除这些资源定义(假设您的应用程序中没有其他任何东西使用它们),这也可能会解决错误。
也就是说,我鼓励您使用这些资源,因为这将使您将来更新应用程序变得更加容易,因为如果您需要更改连接工厂或队列配置,那么您只需修改context.xml
而不是您的应用程序代码。这是 运行 您的应用程序在 Tomcat.
这样的服务器中的主要好处之一
我目前是这样配置我的 Tomcat 的 context.xml
的:
<Resource name="jms/ConnectionFactory" auth="Container" type="org.apache.activemq.ActiveMQConnectionFactory" description="JMS Connection Factory" factory="org.apache.activemq.jndi.JNDIReferenceFactory" brokerURL="tcp://MY_LOCALHOST_URL:7270" brokerName="LocalActiveMQBroker" useEmbeddedBroker="false"/>
<Resource name="AppJms-HVDIVD17CA50359" auth="Container" type="org.apache.activemq.ActiveMQConnectionFactory" factory="org.apache.activemq.jndi.JNDIReferenceFactory" physicalName="APP.QUEUE" />
我有我的 activemq.xml
:
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="appjms" uri="tcp://MY_LOCALHOST_URL:7270?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
我在 Java 中启动 JMS 代码如下:
public void createMessageSubscriberJms(String host, int port, String jmsDestination) throws JMSException, UnknownHostException {
String hostname = InetAddress.getLocalHost().getCanonicalHostName();
String providerEndpoints = "tcp://" + hostname + ":" + port + "?wireFormat.maxInactivityDuration=7200000";
// Set the trusted packages/classes to move back and forth on the ActiveMQ JMS service.
ArrayList<String> trustedClasses = new ArrayList<String>();
trustedClasses.add("com.gtt.common.shared.GTCMessage");
// Obtain the factory
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
activeMQConnectionFactory.setBrokerURL(providerEndpoints);
// Add the trusted packages/classes to the ActiveMQ consumer.
//activeMQConnectionFactory.setTrustedPackages(trustedClasses);
activeMQConnectionFactory.setTrustAllPackages(true);
//Create the connection
setQueueConnection(activeMQConnectionFactory.createQueueConnection());
getQueueConnection().setClientID(this.getName());
// Make a session
setSession(getQueueConnection().createQueueSession(false, Session.AUTO_ACKNOWLEDGE));
getSession().createQueue(jmsDestination);
// Create the destination
Destination destination = getSession().createQueue(jmsDestination);
String selector = "JMSCorrelationID = '" + getActionRequest().getOriginId() + "_" + getActionRequest().getRequestId() + "'" ;
setConsumer(getSession().createConsumer(destination, selector));
getConsumer().setMessageListener(new DefaultMessageListener(this));
// Start ...
// We'll need a message store now
gtcMessages = new GTCMessageQueue<GTCMessage>();
getQueueConnection().start();
}
但是当我启动 Tomcat 并调用该方法时,出现以下错误:
Name [AppJms-HVDIVD17CA50359] is not bound in this Context. Unable to find [AppJms-HVDIVD17CA50359].
你能告诉我我做错了什么吗?当我使用旧版本的 Tomcat 和 ActiveMQ 时,我确信相同的配置有效。
目前我正在使用 Tomcat 9.0.45 和 ActiveMQ 5.16.1。
你对 AppJms-HVDIVD17CA50359
的定义对我来说有点奇怪:
<Resource name="AppJms-HVDIVD17CA50359" auth="Container" type="org.apache.activemq.ActiveMQConnectionFactory" factory="org.apache.activemq.jndi.JNDIReferenceFactory" physicalName="APP.QUEUE" />
看起来您正在定义 JMS 队列,因为 physicalName
属性是 APP.QUEUE
。但是,type
是 org.apache.activemq.ActiveMQConnectionFactory
,这是 JMS 连接工厂而不是队列的正确 type
。此外,org.apache.activemq.ActiveMQConnectionFactory
class 没有 physicalName
属性。我认为你应该在这里使用 org.apache.activemq.command.ActiveMQQueue
作为 type
,例如:
<Resource name="AppJms-HVDIVD17CA50359" auth="Container" type="org.apache.activemq.command.ActiveMQQueue" factory="org.apache.activemq.jndi.JNDIReferenceFactory" physicalName="APP.QUEUE" />
值得注意的是,您似乎没有在此代码中使用 AppJms-HVDIVD17CA50359
或 jms/ConnectionFactory
。我没有看到任何使用这些名称的 JNDI 查找。因此,您可以简单地从 context.xml
中删除这些资源定义(假设您的应用程序中没有其他任何东西使用它们),这也可能会解决错误。
也就是说,我鼓励您使用这些资源,因为这将使您将来更新应用程序变得更加容易,因为如果您需要更改连接工厂或队列配置,那么您只需修改context.xml
而不是您的应用程序代码。这是 运行 您的应用程序在 Tomcat.