You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TomEE无法向ActiveMQ Artemis发送消息但可接收,求解决方案

TomEE无状态服务无法向ActiveMQ Artemis发送消息问题排查与解决

问题描述

我正在配置TomEE向ActiveMQ Artemis发送消息:通过ActiveMQ Artemis控制台发送的消息可被MDB接收,但在ActiveMQ Classic下正常运行的无状态服务无法向ActiveMQ Artemis发送消息,且日志无任何错误。

TomEE配置片段

<Resource id="MyJmsConnectionFactory"
          class-name="org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory"
          constructor="uri,username,password"
          type="jakarta.jms.ConnectionFactory">
    uri=tcp://localhost:61617?needClientAuth=false;sslEnabled=true;trustAll=true;verifyHost=false;wantClientAuth=false;needClientAuth=false
    username=admin
    password=admin 
</Resource> 

<Resource id="TESTQ"
          class-name="org.apache.activemq.artemis.api.jms.ActiveMQJMSClient"
          constructor="name"
          factory-name="createQueue"
          type="jakarta.jms.Queue">
    name=TESTQ
</Resource> 
<Container id="mdb" type="MESSAGE">
    InstanceLimit = -1
    ResourceAdapter = MyJmsResourceAdapter
    ActivationSpecClass = org.apache.activemq.artemis.ra.inflow.ActiveMQActivationSpec
</Container> 

无状态服务注入点

@Stateless 
@Path("/RestTest") 
public class RestTest
{
    @Resource(name = "MyJmsConnectionFactory")
    private ConnectionFactory _connectionFactory ;

    @Resource(name = "TESTQ")
    private Queue testq ;
    .....
}

依赖jar包

  • artemis-jakarta-client-all-2.29.0.jar
  • artemis-jakarta-ra-2.29.0.jar
  • artemis-jakarta-service-extensions-2.29.0.jar
  • OpenEjbTransactionManagerJakarta.jar(适配Jakarta规范的自定义修改版本)

已尝试操作

  • 关闭SSL改用普通TCP连接
  • 在TomEE 8中使用javax相关类
    以上操作均仅MDB能正常工作,无状态服务发送消息问题依旧。

Artemis日志信息

2023-07-21 10:27:21,334 DEBUG
[org.apache.activemq.artemis.core.server.impl.ServerSessionImpl]
Routing result for CoreMessage[messageID=1538,durable=true,userID=b414a064-27d2-11ee-8e7d-00059a3c7a00,priority=4,
timestamp=Fri Jul 21 10:27:21 EDT 2023,expiration=0, durable=true, address=TESTQ,size=1376,
properties=TypedProperties[__AMQ_CID=b40955c1-27d2-11ee-8e7d-00059a3c7a00,_AMQ_ROUTING_TYPE=1
,_AMQ_DUPL_ID=7e335005-1538-488d-ac5e-0f54ebc01ec8,
_HQ_DUPL_ID=7e335005-1538-488d-ac5e-0f54ebc01ec8]]@1370468351 = OK

服务器显示消息路由成功,但控制台无生产者信息,消息也未出现在队列中。


解决方案

1. 排查事务提交逻辑

从Artemis日志来看,服务器已完成消息路由,但队列中无消息,大概率是事务未提交导致消息被回滚:

  • 若使用容器管理事务(默认),确保发送消息的方法没有触发事务回滚的逻辑(如未捕获的异常)。
  • 尝试给发送消息的方法添加@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW),强制开启独立事务,避免受原有事务上下文影响:
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void sendMessage() {
        // 消息发送逻辑
    }
    
  • 若手动管理事务,需显式调用commit()方法:
    UserTransaction ut = InitialContext.doLookup("java:comp/UserTransaction");
    ut.begin();
    try {
        // 发送消息逻辑
        ut.commit();
    } catch (Exception e) {
        ut.rollback();
        e.printStackTrace();
    }
    

2. 调整连接工厂配置

暂时改用非XA连接工厂排除XA事务干扰,将ActiveMQXAConnectionFactory替换为ActiveMQConnectionFactory:

<Resource id="MyJmsConnectionFactory"
          class-name="org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory"
          constructor="uri,username,password"
          type="jakarta.jms.ConnectionFactory">
    uri=tcp://localhost:61617?needClientAuth=false;sslEnabled=true;trustAll=true;verifyHost=false;wantClientAuth=false;needClientAuth=false
    username=admin
    password=admin 
</Resource>

测试是否能正常发送消息,若正常则说明问题出在XA事务的协调上。

3. 修正队列资源配置

Artemis的ActiveMQJMSClient.createQueue方法支持传入address和name两个参数,原配置仅指定name可能导致消息发送到错误的地址。修改队列配置:

<Resource id="TESTQ"
          class-name="org.apache.activemq.artemis.api.jms.ActiveMQJMSClient"
          constructor="address,name"
          factory-name="createQueue"
          type="jakarta.jms.Queue">
    address=TESTQ
    name=TESTQ
</Resource>

同时通过Artemis控制台确认TESTQ队列已正确创建,且地址与配置一致。

4. 校验事务管理器适配

自定义的OpenEjbTransactionManagerJakarta.jar可能存在Jakarta事务规范适配问题:

  • 尝试移除该jar包,使用TomEE原生事务管理器(若不需要XA事务)。
  • 若必须使用XA事务,确保该jar包正确实现了Jakarta Transactions API,特别是XA资源的注册与事务协调逻辑。

5. 开启TomEE JMS日志排查

在TomEE的conf/logging.properties中添加日志配置,捕获JMS发送过程的详细日志:

org.apache.openejb.jms.level = FINE
org.apache.activemq.artemis.jms.level = FINE
java.util.logging.ConsoleHandler.level = FINE

查看TomEE日志,确认消息发送时是否有隐藏的异常或事务回滚信息。


内容的提问来源于stack exchange,提问作者user18896654353

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 22:05:30