Tuesday 22 May 2012

Running a HornetQ Server with Maven

As part of our ongoing efforts to simplify using HornetQ we decided to Mavenize the HornetQ examples. Part of this process was to write something that would automatically start (and stop) a HornetQ server, we decided that writing a Maven plugin to do this would be the simplest way.

Once I had written it I realised that this may be useful to other people so we have created a maven-hornetq-project in github and released the first version which is available in the JBoss repository.

I'll discuss here how to configure a simple maven example that will start a HornetQ server, run a JMS Client and then stop the server.

The plug info you need to add to your build plugins is as follows

<plugin> 
   <groupId>org.hornetq</groupId>
   <artifactId>hornetq-maven-plugin</artifactId> 
   <version>1.0.0</version>
   ..............


After that there are 3 possible execution goals to choose from:

The Start Goal



This Goal basically starts the server, a typical configuration would look as follows:

<execution>
   <id>start</id>
   <goals>
      <goal>start</goal>
   </goals>
   <configuration>
   <fork>false</fork>
   <waitFor>false</waitFor>
   <hornetqConfigurationDir>myConfigurationDir</hornetqConfigurationDir>
   <useJndi>true</useJndi>
   <jndiHost>localhost</jndiHost>
   <jndiPort>1099</jndiPort>
   <jndiRmiPort>1098</jndiRmiPort>
   <systemProperties>
      <property>

         <name>build.directory</name>
         <value>${basedir}/target/</value>
      </property>
   </systemProperties>
   </configuration>
</execution> 

The Following table explains what each configuration element is used for:

name description default
fork Whether or not the server is forked in a new process, if false the server will be started in the same vm as the mvn process although it will have its own classloader. If you are running multiple servers or want some isolation then you should set this to true. false
waitFor Whether or maven should wait until the server has been stopped before returning from the goal, i.e. if set to true maven will just execute the goal and then block. false
hornetqConfigurationDir Where the server should pick up its configuration files from, i.e. hornetq-configuration.xml empty
useJndi Whether or not a JNDI server will be started. true
jndiHost The Host Name that the JNDI server will bind to localhost
jndiPort The port that the JNDI server will bind too 1099
jndiRmiPort The RMI port that the jndi Server will bind too 1098
systemProperties Any System properties you want to set before starting the server. useful when using properties in configuration files. empty

The runClient Goal


The runClient goal will basically run any standalone java client and is configured like so:


<execution>
   <id>runClient</id>
   <goals>
      <goal>runClient</goal>
   </goals>
   <configuration>
      <clientClass>org.hornetq.jms.example.QueueExample</clientClass>
         <args>
         <param>jnp://localhost:1099</param>
      </args>
   </configuration>
</execution>


The Important element here is the clientClass, this basically configures which java class you want to run. The Client also supports setting System properties.

NB You can also configure the normal maven java plugin to run as well as an integration test but since it is sometimes difficult in maven to configure the order of executions between different plugins this makes it easier.

The Stop Goal


The Stop Goal basically does what it says, its stops the HornetQ Server and is configured like so:

<execution>
   <id>stop</id>
   <goals>
      <goal>stop</goal>
   </goals>
   <configuration>
      <hornetqConfigurationDir></hornetqConfigurationDir>
   </configuration>
</execution>

It is important here that you configure the stop goal with the same configuration directory as the start goal.

Configuring the Dependencies


The following dependencies are required to run the HornetQ plugin, the important thing to remember here is that these must be placed in the plugin its self and not the poms main dependencies. Most later versions of HornetQ are supported but I would suggest using the latest and greatest. These would look something like:


<dependencies>
   <dependency>
     <groupId>org.hornetq.example</groupId>
     <artifactId>hornetq-jms-queue-example</artifactId>
     <version>${project.version}</version>
   </dependency>
   <dependency>
     <groupId>org.hornetq</groupId>
     <artifactId>hornetq-core</artifactId>
     <version>2.2.14.Final</version>
   </dependency>
   <dependency>
     <groupId>org.hornetq</groupId>
     <artifactId>hornetq-jms</artifactId>
     <version>2.2.14.Final</version>
   </dependency>
   <dependency>
     <groupId>org.jboss.netty</groupId>
     <artifactId>netty</artifactId>
     <version>3.2.3.Final</version>
   </dependency>
   <dependency>
     <groupId>org.jboss.javaee</groupId>
     <artifactId>jboss-jms-api</artifactId>
     <version>1.1.0.GA</version>
   </dependency>
   <dependency>
     <groupId>org.jboss.naming</groupId>
     <artifactId>jnpserver</artifactId>
     <version>5.0.3.GA</version>
   </dependency>
</dependencies>

One important thing to note here is that the first dependency is needed for the runClient goal and in this case is actually itself, i.e. the group id and artifact id of the same pom.


All the JMS examples currently in the HornetQ master branch at github which you can use as a reference, the snippets in this post come from the JMS queue example.

Messaging with JMS and MDBs on OpenShift

A suite of Quick starts that have been written to demonstrate the use of Java EE 6 on JBoss AS7 have been written and are available here. As part of this suite we have written an example that uses JMS and MDB's to show how to deploy an MDB and post a message to it via a JMS client. The quick start itself can be found here and the Read me takes you through all the steps needed to do deploy and run the example.

The example also demonstrates how to deploy the example using Openshift. OpenShift is Red Hat's free, Cloud Application Platform as a Service offering which allows application developers and teams to build, test, deploy, and run their applications easily. Pete Muir has created a screencast which takes you step by step through how to do this.