JBoss ESB Trailblazer building with Maven 2

Our selected technology stack is JBoss ESB deployed into a JBoss AS. The message providers are a discussion for another day. I am not comfortable with using Ant as the build tool because as the project gets large maintenance will start to become an issue. Furthermore a lot can be said about using convention within a particular company or development team.

 

 

Many large open source efforts are built using maven, including spring and the JBoss AS. JBoss ESB however has not yet made the move over. I suspect because of legacy issues. Wasn't it purchased from somewhere and then open sourced?

 

My first port of call was therefore to create a maven proof of concept using a quickstart from the JBoss ESB distribution. 4.7 for some reason didn't include trailblazer, so I grabbed that from a previous version and went about getting it built.

 

Maven generally dictates a specific project structure, sure it can be changed but I don't want all the complications associated with that, so the first issue is to move files around into a project structure maven is happy with...

 

Project Structure

 

I will first present the standard ESB project structure (based on the quickstart projects bundled with ESB), then contrast that with the maven based structure to enable relative orientation when referring to those useful quickstart applications.

The traditional structure is:

 

 

  • Project Folder

    • Banks

      • src

      • build.xml

      • lib

      • .properties

    • client

      • src

      • resources

        • wsdl

        • web.xml

      • build.xml

      • lib

      • .properties

    • esb

      • src

      • conf

      • build.xml

      • lib

      • .properties

  • .properties

  • build.xml

 

 

 

In contrast the maven structure is:

 

 

  • Project Folder

    • pom.xml

    • module folder 1

    • module folder 2

    • etc...

 

 

Where each module has the following sub structure:

 

 

  • pom.xml

  • src

    • main

      • java

      • resources

    • test

      • java

      • resources

 

 

Where META-INF or WEB-INF is required, these files/folders are located under src/main/resources...

 

POM Hierarchy

 

Now... A POM (Project Object Model) is the maven project file. POMs have aggregates and inheritance. This means that a POM can inherit from another POM and inherit it's dependencies and properties, it also means that one POM can be an aggregate consisting of many modules. This allows us to create a nice hierarchy. The main project folder has a parent POM which specifies the project name, version, dependencies and modules. Each sub folder has a POM which inherits from the parent POM, but specializes for the particular module. The POM is the main folder is therefore a parent and an aggregate POM.

ESBs and indeed many JBoss modules are built to work with a particular version of the App Server, furthermore, many of the JBoss libs aren't available from any repo. The recommended of building with maven is therefore to use the JBoss dependencies from you actual App Server on your machine. Therefore, in the parent POM we declare a set of properties:

 

     <properties>
          <jbossesb.home>c:/jbossesb-server-4.7</jbossesb.home>
          <jbossesb.version>4.7</jbossesb.version>
          <jbossesb.lib>${jbossesb.home}/server/default/deploy/jbossesb.sar/lib</jbossesb.lib>
          <jbossesb.deploy>${jbossesb.home}/server/default/deploy</jbossesb.deploy>
     </properties>

 

Note: You should extract the server path out into a properties file on actual projects...

 

The JBoss dependencies are then declared as system dependencies:

 

          <dependency>
               <groupId>jboss</groupId>
               <artifactId>jbossesb-rosetta</artifactId>
               <version>${jbossesb.version}</version>
               <scope>system</scope>
               <systemPath>${jbossesb.lib}/jbossesb-rosetta.jar</systemPath>
          </dependency>

          <dependency>
               <groupId>jboss</groupId>
               <artifactId>jbossts-common</artifactId>
               <version>1.0</version>
               <scope>system</scope>
               <systemPath>${jbossesb.lib}/jbossts-common.jar</systemPath>
          </dependency>

 

The remaining dependencies are declared in the traditional way:

 

          <dependency>
               <groupId>log4j</groupId>
               <artifactId>log4j</artifactId>
               <version>1.2.15</version>
          </dependency>

 

Then, for the trailblazer (and I assume all apps going forward) we need to ensure that maven uses the correct source compliance level:

 

      <build>
          <pluginManagement>
               <plugins>
                    <plugin>
                         <groupId>org.apache.maven.plugins</groupId>
                         <artifactId>maven-compiler-plugin</artifactId>
                         <version>2.1</version>
                         <configuration>
                              <source>1.5</source>
                              <target>1.5</target>
                         </configuration>
                    </plugin>
               </plugins>
          </pluginManagement>
     </build>

 

Finally, the parent POM also declares which modules make up this project (this is the aggregate part):

     <modules>
          <module>client</module>
          <module>bank</module>
          <module>esb</module>
     </modules>

 

Each of the child POMs then inherits from this parent POM:

 

     <parent>
          <artifactId>trailblazer</artifactId>
          <groupId>za.co.fnb</groupId>
          <version>0.0.1</version>
     </parent>

 

Child Modules

 

Each child module then specializes the parent and adds its own specific configuration. I will talk about the client and esb separately.

The client builds and deploys a .war archive into the app server. The first thing to note is that you can have dependencies between modules:

 

     <dependencies>
          <dependency>
               <groupId>za.co.fnb</groupId>
               <artifactId>trailblazer.esb</artifactId>
               <version>0.0.1-SNAPSHOT</version>
               <type>jar</type>
               <scope>compile</scope>
          </dependency>
     </dependencies>

 

Maven will sort out the build order of modules based on these dependencies...

 

The next important thing is the packaging type for the module, in the case of the client, the packaging is declared as
<packaging>war</packaging>

while in the case of the esb it is declared as

<packaging>jboss-esb</packaging>

 

Each module can also declare it's own dependencies. These are the dependencies of the esb module:

     <dependencies>
          <dependency>
               <groupId>za.co.fnb</groupId>
               <artifactId>hsql</artifactId>
               <version>1.0</version>
               <type>jar</type>
               <scope>compile</scope>
          </dependency>
          <dependency>
               <groupId>za.co.fnb</groupId>
               <artifactId>testutil</artifactId>
               <version>1.0</version>
               <type>jar</type>
               <scope>compile</scope>
          </dependency>
          <dependency>
               <groupId>org.antlr</groupId>
               <artifactId>stringtemplate</artifactId>
               <version>3.2.1</version>
          </dependency>
     </dependencies>

 

Note:Some have to be manually installed into the repo! This especially applies to the Sun Jars, there is a good discussion on this point at http://maven.apache.org/guides/mini/guide-coping-with-sun-jars.html

 

The ESB module requires a plugin to be able to generate the esb archive:

               <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>jboss-packaging-maven-plugin</artifactId>
                    <version>2.1.1</version>
                    <!-- Enable packaging types and lifecycle bindings. -->
                    <extensions>true</extensions>
               </plugin>

 

Then, finally, we need to be able to deploy to the app server. This is done in a fairly manual manner through ant:

               <plugin>
                    <artifactId>maven-antrun-plugin</artifactId>
                    <executions>
                         <execution>
                              <phase>install</phase>
                              <configuration>
                                   <tasks>
                                        <copy file="target/${artifactId}-${version}.esb" tofile="${jbossesb.deploy}/${project.parent.artifactId}.esb"/>
                                   </tasks>
                              </configuration>
                              <goals>
                                   <goal>run</goal>
                              </goals>
                         </execution>
                    </executions>
               </plugin>

 

Note that the properties are available to the ant tasks, even the properties from the parent POM...

 

Attached you will find the complete project files. Any feedback/additions are welcome!