WildFly – ActiveMQ integration part 2: module installation

This is the second tutorial about how to integrate Active MQ broker with WildFly. In the first tutorial we have covered how to install Active MQ RAR file on WildFly:

This tutorial shows how to deploy a Resource Adapter for ActiveMQ as a module and configure a ConnectionFactory and a Queue towards ActiveMQ.

Prerequisite to this tutorial is that you are running a JBoss EAP 6.1/6.2 or Wildfly application server. As for earlier server versions there’s an issue [AS7-5768] “Support resource adapter deployments via modules” which prevents this tutorial from working.

So I suppose you have either WildFly or JBoss EAP 6.1+ up and running: the scenario we are going to describe covers deploying a resource adapter into the application server as module without running embedded broker but rather activemq running standalone in separate process.

First you’d need ActiveMQ server running. Grab it from apache’s activemq site (http://activemq.apache.org/download.html). Once downloaded, unpack activemq server bundle and start it
($AMQ_DIR/bin/activemq console on linux, %AMQ_DIR%\bin\activemq on windows)

Next, you’d need the ActiveMQResource Adapter. Grab it from here:

Since 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.

Module installation on the application server

Create the folder:$JBOSS_HOME/modules/system/layers/base/org/apache/activemq/main/
Copy all unpacked files of resource adapter to that folder, including the META-INF/ra.xml file.
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">
    <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"/>
    <exclude path="org/springframework/**"/>
    <exclude path="org/apache/xbean/**"/>
    <exclude path="org/apache/commons/**"/>
    <exclude path="org/aopalliance/**"/>
    <exclude path="org/fusesource/**"/>
    <module name="javax.api"/>
    <module name="org.slf4j"/>
    <module name="javax.resource.api"/>
    <module name="javax.jms.api"/>
    <module name="javax.management.j2ee.api"/>

Note on <exclude path> section: 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.

Here’s how the structure of your module should look like:

    |   activemq-broker-5.9.0.jar
    |   activemq-client-5.9.0.jar
    |   activemq-jms-pool-5.9.0.jar
    |   activemq-kahadb-store-5.9.0.jar
    |   activemq-openwire-legacy-5.9.0.jar
    |   activemq-pool-5.9.0.jar
    |   activemq-protobuf-1.1.jar
    |   activemq-ra-5.9.0.jar
    |   activemq-spring-5.9.0.jar
    |   aopalliance-1.0.jar
    |   commons-logging-1.1.3.jar
    |   commons-net-3.3.jar
    |   commons-pool-1.6.jar
    |   geronimo-j2ee-management_1.1_spec-1.0.1.jar
    |   hawtbuf-1.9.jar
    |   log4j-1.2.17.jar
    |   module.xml
    |   slf4j-api-1.7.5.jar
    |   slf4j-log4j12-1.7.5.jar
    |   spring-aop-3.2.4.RELEASE.jar
    |   spring-beans-3.2.4.RELEASE.jar
    |   spring-context-3.2.4.RELEASE.jar
    |   spring-core-3.2.4.RELEASE.jar
    |   spring-expression-3.2.4.RELEASE.jar
    |   xbean-spring-3.14.jar
    |   META-INF

Module Configuration

Next thing is to configure resource adapter. Open your configuration file and add the following node within the resource-adapter subsystem:

    <resource-adapter id="activemq-rar.rar">
        <module slot="main" id="org.apache.activemq"/>
        <config-property name="ServerUrl">
            <connection-definition class-name="org.apache.activemq.ra.ActiveMQManagedConnectionFactory" jndi-name="java:/ConnectionFactory" enabled="true" use-java-context="true" pool-name="ConnectionFactory"/>
            <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">

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.