TomEE: JMS Provider - ActiveMQ with AMQP Wire 协议

TomEE: JMS Provider - ActiveMQ with AMQP Wire protocol

我正在尝试配置 TomEE(Tomcat 和 Java EE)以使用 AMQP 有线协议连接到外部代理(Azure 服务总线)。看起来默认情况下 JMS 提供程序是 ActiveMQ。根据文档,ActiveMQ 确实支持 AMQP 协议。我的目标是使用 ActiveMQ 作为 TomEE 提供的 JMS 提供程序。但是,当我部署我的基本 ear 文件时,出现以下错误:

03-Jun-2019 16:43:19.629 WARNING [http-nio-8080-exec-1] org.apache.geronimo.transaction.manager.TransactionImpl.enlistResource Unable to enlist XAResource org.apache.geronimo.transaction.manager.WrapperNamedXAResource@117d2011, errorCode: -7
 javax.transaction.xa.XAException: Disposed due to prior exception
    at org.apache.activemq.TransactionContext.toXAException(TransactionContext.java:803)
    at org.apache.activemq.TransactionContext.setXid(TransactionContext.java:729)
    at org.apache.activemq.TransactionContext.start(TransactionContext.java:379)
    at org.apache.activemq.ra.LocalAndXATransaction.start(LocalAndXATransaction.java:151)
    at org.apache.geronimo.transaction.manager.WrapperNamedXAResource.start(WrapperNamedXAResource.java:111)
    at org.apache.geronimo.transaction.manager.TransactionImpl.enlistResource(TransactionImpl.java:209)
    at org.apache.geronimo.connector.outbound.TransactionEnlistingInterceptor.getConnection(TransactionEnlistingInterceptor.java:60)
    at org.apache.geronimo.connector.outbound.TransactionCachingInterceptor.getConnection(TransactionCachingInterceptor.java:101)
    at org.apache.geronimo.connector.outbound.ConnectionHandleInterceptor.getConnection(ConnectionHandleInterceptor.java:43)
    at org.apache.geronimo.connector.outbound.TCCLInterceptor.getConnection(TCCLInterceptor.java:39)
    at org.apache.geronimo.connector.outbound.ConnectionTrackingInterceptor.getConnection(ConnectionTrackingInterceptor.java:66)
    at org.apache.geronimo.connector.outbound.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:81)
    at org.apache.activemq.ra.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:94)
    at org.apache.activemq.ra.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:67)
    at local.gerb.HelloImpl.sendJMS(HelloImpl.java:79)

[....]

Caused by: org.apache.activemq.transport.InactivityIOException: Channel was inactive for too (>30000) long: tcp://40.71.10.195:5671
    at org.apache.activemq.transport.amqp.AmqpInactivityMonitor.run(AmqpInactivityMonitor.java:69)
    ... 3 more

有人用过 ActiveMQ 和 AMQP 吗?或者有没有人得到它与 Azure 服务总线一起使用的奖励积分?

我确实尝试了从 github 开始的 Azure JMS 快速启动:(https://github.com/Azure/azure-service-bus/tree/master/samples/Java/qpid-jms-client/JmsQueueQuickstart) 并且它正在运行,所以我相信服务总线已经启动并且 运行。但是,我无法在 TomEE 中部署 JMS 应用程序。任何帮助将不胜感激。

更新:我正在使用 Justin Bertram 建议的 AMPQ 资源适配器:https://github.com/amqphub/amqp-10-resource-adapter

我将 rar 包含在我的 ear 文件中,TomEE 似乎成功加载了资源适配器:

04-Jun-2019 02:21:02.117 INFO [main] org.apache.openejb.config.OutputGeneratedDescriptors.writeRaXml Dumping Generated ra.xml to: /usr/local/tomee/temp/ra-6070887435985632449resource-adapter-1.0.1-SNAPSHOT.rar.xml
04-Jun-2019 02:21:02.140 INFO [main] org.apache.openejb.config.ConfigurationFactory.configureService Configuring Service(id=AmqpResourceAdapter, type=Resource, provider-id=AmqpResourceAdapter)
04-Jun-2019 02:21:02.142 INFO [main] org.apache.openejb.config.ConfigurationFactory.configureService Configuring Service(id=resource-adapter-1.0.1-SNAPSHOT.rar, type=Resource, provider-id=resource-adapter-1.0.1-SNAPSHOT.rar)
04-Jun-2019 02:21:02.142 INFO [main] org.apache.openejb.config.ConfigurationFactory.configureService Configuring Service(id=resource-adapter-1.0.1-SNAPSHOT.rar, type=Container, provider-id=Default MDB Container)

但是后来在TomEE的启动过程中好像失败了。 ActiveMQ 资源适配器和 AMPQ 资源适配器似乎相互冲突。现在我得到 javax.naming.NameAlreadyBoundException:

04-Jun-2019 02:21:03.947 SEVERE [main] org.apache.tomee.catalina.ServerListener.lifecycleEvent TomEE Listener can't start OpenEJB
 org.apache.openejb.OpenEJBException: Cannot bind Container with id Default MDB Container : ParsedName{path=openejb/Container/Default MDB Container, component=Default MDB Container}
    at org.apache.openejb.assembler.classic.Assembler.bindService(Assembler.java:2847)
    at org.apache.openejb.assembler.classic.Assembler.createContainer(Assembler.java:2817)
    at org.apache.openejb.assembler.classic.Assembler.buildContainerSystem(Assembler.java:623)
    at org.apache.openejb.assembler.classic.Assembler.build(Assembler.java:487)
    at org.apache.openejb.OpenEJB$Instance.<init>(OpenEJB.java:150)
    at org.apache.openejb.OpenEJB.init(OpenEJB.java:307)
    at org.apache.tomee.catalina.TomcatLoader.initialize(TomcatLoader.java:247)
    at org.apache.tomee.catalina.ServerListener.lifecycleEvent(ServerListener.java:168)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:94)
    at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:395)
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:108)
    at org.apache.catalina.startup.Catalina.load(Catalina.java:632)
    at org.apache.catalina.startup.Catalina.load(Catalina.java:655)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:309)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)
Caused by: javax.naming.NameAlreadyBoundException: ParsedName{path=openejb/Container/Default MDB Container, component=Default MDB Container}
    at org.apache.openejb.core.ivm.naming.NameNode.bind(NameNode.java:181)
    at org.apache.openejb.core.ivm.naming.IvmContext.bind(IvmContext.java:322)
    at org.apache.openejb.assembler.classic.Assembler.bindService(Assembler.java:2845)

看来问题出在这里(我认为):

org.apache.openejb.config.ConfigurationFactory.configureService Configuring Service(id=resource-adapter-1.0.1-SNAPSHOT.rar, type=Container, provider-id=Default MDB Container

ActiveMQ 和 AMPQ 似乎都有一个默认 MDB 容器,这导致在部署时抛出异常。但是,我不确定如何配置 AMPQ RA 以使用不同的名称。

我找不到很多关于如何在 TomEE 中配置 RA 的信息。我唯一遇到的是这个文档:http://tomee.apache.org/changing-jms-implementations.html

但它似乎没有详细说明,所以我有点不知道下一步该怎么做。

非常感谢大家的帮助。我觉得我已经非常接近完成这项工作了!

我认为您混淆了经纪人和客户。我已经将 ActiveMQ 与 AMQP 一起使用,但它是一个连接到 ActiveMQ 代理的 AMQP 客户端。您正在尝试使用 ActiveMQ JCA 资源适配器,它旨在通过 OpenWire 协议与 ActiveMQ 代理对话,以使用 AMQP 连接到 Azure 服务总线。这不会起作用,而且从来没有设计成起作用。

您需要使用可以使用 AMQP 的 JCA 资源适配器(即不是 ActiveMQ JCA RA)。也许看看 this generic JMS JCA resource adapter. It was designed to be used in JBoss AS or Wildfly, but there shouldn't be anything precluding its use in TomEE. You can then plug Qpid JMS into that as the client. You can see an example of another component which does this here.