Tuesday 10 December 2013

Deploying ActiveMQ (5.9.0) resource adapter as JBoss EAP module


After searching around JBoss community forum, JBoss AS documentation, googling (of course) and checking out RedHat's EAP documentation
I came up to summarize my findings in this blog entry.
Before everything else, prerequisite for resource adapter to be available as module is to use JBoss EAP 6.1 or later,
as this issue:[AS7-5768] Support resource adapter deployments via modules - JBoss Issue Tracker has been fixed in version 6.1. I've tested with 6.2 as well.

I suppose you have JBoss EAP 6.1+ up and running.

Scenario which I'm describing here covers deploying resource adapter into JBoss as module without running embedded broker but rather activemq running standalone in separate process. Note that I haven't tried/tested embedded broker scenario.

First you'd need ActiveMQ server running. Grab it from apache's activemq site.
Second, you'd need resource adapter. Grab it from here:
 
https://repository.apache.org/content/repositories/releases/org-apache/activemq/activemq-rar/5.9.0/

Unpack activemq server bundle and start it
(
$AMQ_DIR/bin/activemq console on linux, %AMQ_DIR%\bin\activemq on windows)

JBoss EAP 6.1 supports only unpacked resource adapter deployment so, unpack it into some temporary directory.

Open 
META-INF/ra.xml file and locate the following comment:<!-- NOTE disable the following property if you do not wish to deploy an embedded broker -->

It demarcates config property which you should comment out/remove to disable embedded broker. So either comment it out or remove it completely. Save the file.

Create folder:
$JBOSS_HOME/modules/system/layers/base/org/apache/activemq/main/
Copy all unpacked files of resource adapter to that folder. Add module.xml file to the same folder with the following content:

<module xmlns="urn:jboss:module:1.1" name="org.apache.activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<resources>

<resource-root path="."/>
<resource-root path="activemq-broker-5.9.0.jar"/>
<resource-root path="activemq-client-5.9.0.jar"/>
<resource-root path="activemq-jms-pool-5.9.0.jar"/>
<resource-root path="activemq-kahadb-store-5.9.0.jar"/>
<resource-root path="activemq-openwire-legacy-5.9.0.jar"/>
<resource-root path="activemq-pool-5.9.0.jar"/>
<resource-root path="activemq-protobuf-1.1.jar"/>
<resource-root path="activemq-ra-5.9.0.jar"/>
<resource-root path="activemq-spring-5.9.0.jar"/>
<resource-root path="aopalliance-1.0.jar"/>
<resource-root path="commons-pool-1.6.jar"/>
<resource-root path="commons-logging-1.1.3.jar"/>
<resource-root path="hawtbuf-1.9.jar"/>
<resource-root path="spring-aop-3.2.4.RELEASE.jar"/>
<resource-root path="spring-beans-3.2.4.RELEASE.jar"/>
<resource-root path="spring-context-3.2.4.RELEASE.jar"/>
<resource-root path="spring-core-3.2.4.RELEASE.jar"/>
<resource-root path="spring-expression-3.2.4.RELEASE.jar"/>
<resource-root path="xbean-spring-3.14.jar"/>

</resources>
<exports>

<exclude path="org/springframework/**"/>
<exclude path="org/apache/xbean/**"/>
<exclude path="org/apache/commons/**"/>
<exclude path="org/aopalliance/**"/>
<exclude path="org/fusesource/**"/>

</exports>

<dependencies>

<module name="javax.api"/>
<module name="org.slf4j"/>
<module name="javax.resource.api"/>
<module name="javax.jms.api"/>
<module name="javax.management.j2ee.api"/>

</dependencies>

</module>


Note on <exclude path= elements: I've added those to exclude mentioned packages because I don't really want that classes to clash with my deployments where I use specific version of spring/aopalliance artifacts.
If you really need to depend/import some classes from resource adapter directly in your code then IMHO you are doing something wrong 
Anyway, next thing is to configure resource adapter. Open standalone.xml and within

<subsystem xmlns="urn:jboss:domain:resource-adapters:1.1">


node add the following snippet:

<resource-adapters>
<resource-adapter id="org.apache.activemq.ra">
<module slot="main" id="org.apache.activemq"/>
<transaction-support>NoTransaction</transaction-support>
<config-property name="ServerUrl">
tcp://localhost:61616
</config-property>
<connection-definitions>
<connection-definition class-name="org.apache.activemq.ra.ActiveMQManagedConnectionFactory" jndi-name="java:/ConnectionFactory" enabled="true" use-java-context="true" pool-name="ConnectionFactory"/>
</connection-definitions>
<admin-objects>
<admin-object class-name="org.apache.activemq.command.ActiveMQQueue" jndi-name="queue/test-queue" use-java-context="true" pool-name="test_queue">
<config-property name="PhysicalName">testQueue</config-property>
</admin-object>
</admin-objects>
</resource-adapter>
</resource-adapters>
Now, (re)start your JBoss application server.
If everything is set correctly, in output/console/server log you should have line something like:

18:13:16,331 INFO  [org.jboss.as.connector.deployment] (MSC service thread 1-16) JBAS010405: Registered admin object at java:/queue/test-queue

From here on, you should be able to use connection factory and queue as usual in Java EE application.

Update (Dec. 26th):
I've faced with issue if resource adapter id ends with ".rar" when deployed as module.
So, give it a name/id like org.apache.activemq.ra and you should be fine.
I've fixed example above.

Apologies for confusion I possibly made...