I'm trying to configure TomEE (Tomcat with Java EE) to connect to an external broker (Azure Service Bus) using the AMQP Wire Protocol. It looks like by default the JMS Provider is ActiveMQ. According to the documentation, ActiveMQ does support the AMQP protocol. My goal is to use ActiveMQ as the JMS Provider that is provided with TomEE. However, when I deploy my basic ear file, I get the following error:
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$1$1.run(AmqpInactivityMonitor.java:69)
... 3 more
Has anyone used ActiveMQ with AMQP? Or for bonus points did anyone get it working with the Azure Service Bus?
I did try the Azure JMS Quick start from github: (https://github.com/Azure/azure-service-bus/tree/master/samples/Java/qpid-jms-client/JmsQueueQuickstart) and that is working so I'm confident the Service Bus is up and running. However, I'm unable to deploy a JMS application in TomEE. Any help would be greatly appreciated.
Update: I'm using the AMPQ resource adapter that Justin Bertram suggest: https://github.com/amqphub/amqp-10-resource-adapter
I included the rar inside my ear file and TomEE seems to load the resource adapter successfully:
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)
But it seems to fail later in start up process of TomEE. It seems like the ActiveMQ Resource Adapter and AMPQ Resource Adapter are in conflict with each other. Now I'm getting 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)
It looks like this is the issue (I think):
org.apache.openejb.config.ConfigurationFactory.configureService Configuring Service(id=resource-adapter-1.0.1-SNAPSHOT.rar, type=Container, provider-id=Default MDB Container
Both ActiveMQ and AMPQ seem to have a Default MDB Container which is causing the exception to be thrown on deployment. However, I'm not sure how to configure the AMPQ RA to use a different name.
I can't find a lot of information on how to configure an RA in TomEE. The only thing I came across is this document: http://tomee.apache.org/changing-jms-implementations.html
But its seem to be a bit light on detail so I'm a little lost on what to do next.
I do appreciate everyone's help. I feel like I'm very close to getting this working!
I think you're confusing brokers and clients. I've used ActiveMQ with AMQP, but it was an AMQP client connecting to an ActiveMQ broker. You're trying to use the ActiveMQ JCA resource adapter which is meant to speak the OpenWire protocol to the ActiveMQ broker to connect to Azure Service Bus using AMQP. This isn't going to work and was never designed to work.
You need to use a JCA resource adapter that can speak AMQP (i.e. not the ActiveMQ JCA RA). Maybe take a look at 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.