无法在 java web servlet 中直接调用 ActiveMQConnection class
Can't invoke ActiveMQConnection class directly in a java web servlet
问题:
我正在尝试使用 ActiveMQConnection
对象设置超时以在我的 Java servlet 中调用 setSendTimeout
方法,但是当调用该代码时,我得到:
Warning: RAR5038:Unexpected exception while creating resource for pool jms_amq_conn_pool. Exception : javax.resource.ResourceException: Could not create connection.
Warning: RAR5117 : Failed to obtain/create connection from connection pool [ jms_amq_conn_pool ]. Reason : com.sun.appserv.connectors.internal.api.PoolingException: Could not create connection.
我该如何解决这个问题?
问题更详细:
我有一个 Payara 服务器,它加载了我调用的 servlet 的 activemq-rar 资源。我跟着 these instructions 去做了。
这是一个突出显示 link 中的步骤的列表:
- 获取 activemq rar 文件以部署到 Payara 服务器。
- 配置 ActiveMQ 连接器
- 创建 JMS 连接池
- 通过创建 JMS 资源创建到 JMS 连接池的 JNDI 映射。
我有 Java servlet 代码,看起来像这样,当我希望它发送消息时可以正常工作:
/**
* Creates a connection using Payara resource then creates a producer/consumer then sends a message.
*/
public void sendAMQMessage() {
javax.jms.ConnectionFactory connectionFactory = InitialContext.doLookup("servlet_jms_amq_conn_factory");
javax.jms.Connection connection = connectionFactory.createConnection();
// creation is created, now set the client id and start it
connection.setClientID("test_client_id");
connection.start();
javax.jms.Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
javax.jms.TemporaryQueue queue = session.createTemporaryQueue();
javax.jms.MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(this);
javax.jms.Queue serviceQueue = session.createQueue("queue_name");
javax.jms.MessageProducer producer = session.createProducer(serviceQueue);
producer.send("data");
}
@Override
public void onMessage(Message message) {
// receives data back from the initial request.
}
当前的网络应用程序 pom.xml
没有引用 ActiveMQ 库,因为上面的代码没有导入任何 ActiveMQ 类。但我想对 Java servlet 发送的消息实施超时,以便如果接收应用程序在一定时间内没有响应,我可以处理。
javax.jms.Connection
没有超时 setter 方法。
ActiveMQConnection
JavaDoc 确实有一个 setSendTimeout(int sendTimeout)
。所以我在应用程序的 pom.xml
:
中包含了 ActiveMQ 依赖项
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.10.0</version>
<type>jar</type>
</dependency>
然后当我更新上面的 sendAMQMessage
方法以使用 setSendTimeout(int sendTimeout)
:
int milliseconds = 10000; // 10,000 ms = 10 seconds
((ActiveMQConnection)connection).setSendTimeout(milliseconds);
然后是 运行 我收到这些警告和异常消息的代码:
Warning: RAR5038:Unexpected exception while creating resource for pool jms_amq_conn_pool. Exception : javax.resource.ResourceException: Could not create connection.
Warning: RAR5117 : Failed to obtain/create connection from connection pool [ jms_amq_conn_pool ]. Reason : com.sun.appserv.connectors.internal.api.PoolingException: Could not create connection.
Warning: RAR5038:Unexpected exception while creating resource for pool jms_amq_conn_pool. Exception : javax.resource.ResourceException: Could not create connection.
Warning: RAR5117 : Failed to obtain/create connection from connection pool [ jms_amq_conn_pool ]. Reason : com.sun.appserv.connectors.internal.api.PoolingException: Could not create connection.
javax.jms.JMSException: Error in allocating a connection. Cause: Could not create connection.
at org.apache.activemq.ra.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:101)
at org.apache.activemq.ra.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:67)
我查看了 this link,上面说只需将 jar 复制到 Payara 服务器的 domains/domain1/ilb/ext
文件夹中。所以我用 activemq-all-5.10.0.jar
做到了,然后当我 运行 上面的代码时,我得到了这个异常:
java.lang.ClassCastException: org.apache.activemq.command.ActiveMQQueue cannot be cast to javax.jms.Queue
一定有办法解决这个问题。有人有想法吗?
您指的超时与接收消息的消费者“响应”所需的时间无关。超时只是关于发送客户端等待代理确认它确实收到消息的时间。这发生在消费者收到消息之前。
如果您要使用 JMS 实现 request/response 功能,那么您应该遵循正确的模式,使用关联 ID 或临时回复队列。
鉴于您正在使用 ActiveMQ JCA 资源适配器,您的客户端实际从 JNDI 查找中获得的连接实现很可能会被容器的 JCA 实现包装。您不太可能能够简单地将其转换为 ActiveMQ 实现。此外,所有 ActiveMQ 客户端 类 都打包在 JCA 资源适配器存档中并与您的应用程序隔离。如果将相同的 类 放在运行时环境中的其他位置,则可能会出现奇怪的类加载行为(例如,意外的 ClassCastException
)。 Java EE 应用程序服务器旨在提供对 Java EE API(例如 JMS、JDBC、JNDI 等)的访问权限。访问底层实现以执行不可移植的操作通常很困难且不鼓励。
问题:
我正在尝试使用 ActiveMQConnection
对象设置超时以在我的 Java servlet 中调用 setSendTimeout
方法,但是当调用该代码时,我得到:
Warning: RAR5038:Unexpected exception while creating resource for pool jms_amq_conn_pool. Exception : javax.resource.ResourceException: Could not create connection.
Warning: RAR5117 : Failed to obtain/create connection from connection pool [ jms_amq_conn_pool ]. Reason : com.sun.appserv.connectors.internal.api.PoolingException: Could not create connection.
我该如何解决这个问题?
问题更详细:
我有一个 Payara 服务器,它加载了我调用的 servlet 的 activemq-rar 资源。我跟着 these instructions 去做了。
这是一个突出显示 link 中的步骤的列表:
- 获取 activemq rar 文件以部署到 Payara 服务器。
- 配置 ActiveMQ 连接器
- 创建 JMS 连接池
- 通过创建 JMS 资源创建到 JMS 连接池的 JNDI 映射。
我有 Java servlet 代码,看起来像这样,当我希望它发送消息时可以正常工作:
/**
* Creates a connection using Payara resource then creates a producer/consumer then sends a message.
*/
public void sendAMQMessage() {
javax.jms.ConnectionFactory connectionFactory = InitialContext.doLookup("servlet_jms_amq_conn_factory");
javax.jms.Connection connection = connectionFactory.createConnection();
// creation is created, now set the client id and start it
connection.setClientID("test_client_id");
connection.start();
javax.jms.Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
javax.jms.TemporaryQueue queue = session.createTemporaryQueue();
javax.jms.MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(this);
javax.jms.Queue serviceQueue = session.createQueue("queue_name");
javax.jms.MessageProducer producer = session.createProducer(serviceQueue);
producer.send("data");
}
@Override
public void onMessage(Message message) {
// receives data back from the initial request.
}
当前的网络应用程序 pom.xml
没有引用 ActiveMQ 库,因为上面的代码没有导入任何 ActiveMQ 类。但我想对 Java servlet 发送的消息实施超时,以便如果接收应用程序在一定时间内没有响应,我可以处理。
javax.jms.Connection
没有超时 setter 方法。
ActiveMQConnection
JavaDoc 确实有一个 setSendTimeout(int sendTimeout)
。所以我在应用程序的 pom.xml
:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.10.0</version>
<type>jar</type>
</dependency>
然后当我更新上面的 sendAMQMessage
方法以使用 setSendTimeout(int sendTimeout)
:
int milliseconds = 10000; // 10,000 ms = 10 seconds
((ActiveMQConnection)connection).setSendTimeout(milliseconds);
然后是 运行 我收到这些警告和异常消息的代码:
Warning: RAR5038:Unexpected exception while creating resource for pool jms_amq_conn_pool. Exception : javax.resource.ResourceException: Could not create connection.
Warning: RAR5117 : Failed to obtain/create connection from connection pool [ jms_amq_conn_pool ]. Reason : com.sun.appserv.connectors.internal.api.PoolingException: Could not create connection.
Warning: RAR5038:Unexpected exception while creating resource for pool jms_amq_conn_pool. Exception : javax.resource.ResourceException: Could not create connection.
Warning: RAR5117 : Failed to obtain/create connection from connection pool [ jms_amq_conn_pool ]. Reason : com.sun.appserv.connectors.internal.api.PoolingException: Could not create connection.
javax.jms.JMSException: Error in allocating a connection. Cause: Could not create connection.
at org.apache.activemq.ra.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:101)
at org.apache.activemq.ra.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:67)
我查看了 this link,上面说只需将 jar 复制到 Payara 服务器的 domains/domain1/ilb/ext
文件夹中。所以我用 activemq-all-5.10.0.jar
做到了,然后当我 运行 上面的代码时,我得到了这个异常:
java.lang.ClassCastException: org.apache.activemq.command.ActiveMQQueue cannot be cast to javax.jms.Queue
一定有办法解决这个问题。有人有想法吗?
您指的超时与接收消息的消费者“响应”所需的时间无关。超时只是关于发送客户端等待代理确认它确实收到消息的时间。这发生在消费者收到消息之前。
如果您要使用 JMS 实现 request/response 功能,那么您应该遵循正确的模式,使用关联 ID 或临时回复队列。
鉴于您正在使用 ActiveMQ JCA 资源适配器,您的客户端实际从 JNDI 查找中获得的连接实现很可能会被容器的 JCA 实现包装。您不太可能能够简单地将其转换为 ActiveMQ 实现。此外,所有 ActiveMQ 客户端 类 都打包在 JCA 资源适配器存档中并与您的应用程序隔离。如果将相同的 类 放在运行时环境中的其他位置,则可能会出现奇怪的类加载行为(例如,意外的 ClassCastException
)。 Java EE 应用程序服务器旨在提供对 Java EE API(例如 JMS、JDBC、JNDI 等)的访问权限。访问底层实现以执行不可移植的操作通常很困难且不鼓励。