Wednesday, 8 October 2014

Generating toString() method in JAX-B generated classes

First of all, this post is inspired by this blog post by Dustin Marx.

What is described below is what you should do with Maven to achieve similar goals in contrast with original post where Ant is used.

So, in your pom.xml of module where generated classes will reside, simply
within <build>/<plugins> section include the following snippet:


<plugin>
     <groupId>org.codehaus.mojo</groupId>
     <artifactId>jaxb2-maven-plugin</artifactId>
     <dependencies>
           <dependency>
                <groupId>org.jvnet.jaxb2_commons</groupId>
                <artifactId>jaxb2-basics</artifactId>
                <version>0.9.0</version>
           </dependency>
      </dependencies>
            <executions>
                    <execution>
                        <id>xjc2</id>
                        <goals>
                            <goal>xjc</goal>
                        </goals>
                        <configuration>
                            <arguments>-XtoString</arguments>
                            <extension>true</extension>
                            <packageName>your.desired.package</packageName>                             <schemaDirectory>/location/of/schema.xsd</schemaDirectory>
                    </configuration>
             </execution>
     </executions>

</plugin>

Now, your further build will fail (unless you are already ahead and have foreseen what is required in addition to given above) saying:
package org.jvnet.jaxb2_commons.lang does not exist

Not too surprising as generated code is again dependent on jaxb2-basics artifact as generated
toString method is referencing it, e.g:

public String toString() {
    final ToStringStrategy strategy = JAXBToStringStrategy.INSTANCE;
    final StringBuilder buffer = new StringBuilder();
    append(null, buffer, strategy);
    return buffer.toString();

}

You will need same dependency as your's module dependency for everything to work as expected.
So under <project>/<dependencies> add:


<dependency>

       <groupId>org.jvnet.jaxb2_commons</groupId>
       <artifactId>jaxb2-basics</artifactId>
       <version>0.9.0</version>
</dependency>

Of course, you can opt for factoring this out into dependency and plugin management sections of your parent module, but that is another story :)

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