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

13 comments:

  1. I've found that if you want to use this resource adapter as default for MDB, then you should change resource-adapter-ref (as usuall), but referenced name has to have *.rar posfix. For example:

    <resource-adapter-ref resource-adapter-name="org.apache.activemq.ra.rar"/>

    with resource adapter defined as in the example:
    <resource-adapter id="org.apache.activemq.ra">
    <module slot="main" id="org.apache.activemq.ra"/>

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Hey Kciuk, are you sure about that? I have checked and when using EAPs 6.1 and 6.2 I have had no issue when specifying id for default resource adapter exactly as it is specified in resource adapter configuration...

    ReplyDelete
  4. Hey,
    yeah you''re right. Must have had something else wrong when I tried that. Sorry for the confusion

    ReplyDelete
  5. Hi,
    Where can i set sendTimeout property of org.apache.activemq.ActiveMQConnectionFactory in this approach?

    ReplyDelete
    Replies
    1. Hi, notice this:

      tcp://localhost:61616

      in jboss resource adapter configuration (check snippet in post)
      as per:
      http://activemq.apache.org/tcp-transport-reference.html
      you can set it via server url/query parameter.

      Hope that helps.

      Delete
  6. Thanks,
    I saw that link, but it hasn't any parameter for sendTimeout. I also tried connection.sendTimout and transport.connection.sendTimout (in below link), but i get "invalid connect parameters" error in Jboss startup.
    http://activemq.apache.org/cms/configuring.html

    Invalid connect parameters: {connection.sendTimeout=20000}

    ReplyDelete
  7. Aha, sorry, somehow I read that you want to set connection timeout (missed out it is "sendTimeout") well, as this is EE domain and what you use is resource adapter and connection factory managed by EE container, ActiveMQManagedConnectionFactory does not provide this property at all.

    However, not everything is lost although you would need to cheat a bit.
    You could inject connection factory into desired bean, fetch connection, then you'll have to cast it to ActiveMQConnection and set that timeout as that is not part of standard JMS API.

    Hope it is more clear now.
    Cheers,

    ReplyDelete
  8. Hi Rastko,

    I am trying to integrate ActiveMQ and the domain that I have created in JBoss , I have followed the steps and instead of editing standalone.xml , I updated the domain.xml under configuration directory but it seems that it is not working because it is not showing in the logs upon start up.

    Am I lacking something?

    I hope you could respond to my reply. Thank you!

    Cheers,
    Matt

    ReplyDelete
    Replies
    1. Hello Matthew, me too. I configured everything as mentioned in the example but in domain.xml
      I pasted the example subsystem under


      But I do see nothing in the log as author mentioned above.

      Rastko - please reply.

      Delete
  9. Well to be honest I haven't really tried to deploy this in domain mode and the post
    is related to standalone configuration. Of course I am willing to help.
    Are you able to see connection definition or admin objects in Resource Adapters page on JBoss console?

    ReplyDelete
  10. Hi, I have followed all the steps, but keep on getting:

    15:19:20,787 ERROR [org.jboss.as.controller.management-operation] (ServerService Thread Pool -- 44) JBAS014612: Operation ("add") failed - address: ([
    ("subsystem" => "resource-adapters"),
    ("resource-adapter" => "org.apache.activemq.ra")
    ]) - failure description: "JBAS010473: Failed to load module for RA [org.apache.activemq]"



    15:19:23,613 ERROR [org.jboss.as] (Controller Boot Thread) JBAS015875: JBoss EAP 6.4.0.GA (AS 7.5.0.Final-redhat-21) started (with errors) in 4592ms - Started 389 of 428 services (1 services failed or missing dependencies, 65 services are lazy, passive or on-demand)




    When starting the EAP 6.4.0

    Thanks in advance!

    ReplyDelete
  11. Well, being this quite a long ago... it probably needs updating...
    what version of RA you are trying with?

    Thinks to check up front:
    1. Name of module in module.xml matches to module specified in resource adapter configuration.
    2. Content of module.xml references proper versions of jars from your unpacked rar archive.

    I am currently running AMQ 5.10 and EAP 6.3.2 without problem
    where all instructions apply with just jars versions adjustments.

    Perhaps you can locate more info on error before that log entry or by decreasing log level?

    ReplyDelete