Tuesday 1 September 2009

A HornetQ Simple Example using Maven

Since HornetQ can be run embedded and can be run with no little or no thirdparty dependencies, its easy to create a simple project that runs an embedded server or simple client. The example code can be downloaded from here and can be built and run as follows: To build both the embedded server and client run mvn package from the root directory. To run the server run mvn exec:java from the embedded-server directory. To run the client run mvn exec:java from the client directory. Now lets look more closely at both examples in more detail. embedded server Lets start by looking at the dependencies in the pom.xml found under the embedded-server directory. The dependencies needed are configured as follows:
<dependencies>
  <dependency>
     <groupId>org.hornetq</groupId>
     <artifactId>hornetq-core</artifactId>
     <version>2.0.0.GA</version>
     <scope>compile</scope>
  </dependency>
  <dependency>
     <groupId>org.hornetq</groupId>
     <artifactId>hornetq-jms</artifactId>
     <version>2.0.0.GA</version>
     <scope>compile</scope>
  </dependency>
  <dependency>
     <groupId>org.hornetq</groupId>
     <artifactId>hornetq-logging</artifactId>
     <version>2.0.0.GA</version>
     <scope>compile</scope>
  </dependency>
  <dependency>
     <groupId>org.hornetq</groupId>
     <artifactId>hornetq-transports</artifactId>
     <version>2.0.0.GA</version>
     <scope>compile</scope>
  </dependency>
  <dependency>
     <groupId>org.jboss.netty</groupId>
     <artifactId>netty</artifactId>
     <version>3.1.0.GA</version>
  </dependency>
  <dependency>
     <groupId>org.jboss.javaee</groupId>
     <artifactId>jboss-jms-api</artifactId>
     <version>1.1.0.GA</version>
     <scope>compile</scope>
  </dependency>
These dependencies are what you would need to run a HornetQ JMS server now lets look at the code needed to run an embedded server:
public class EmbeddedServer
{
public static void main(String[] args) throws Exception
{
  try
  {
     FileConfiguration configuration = new FileConfiguration();
     configuration.setConfigurationUrl("hornetq-configuration.xml");
     configuration.start();

     HornetQServer server = HornetQServers.newHornetQServer(configuration);
     JMSServerManager jmsServerManager = new JMSServerManagerImpl(server, "hornetq-jms.xml");
     //if you want to use JNDI, simple inject a context here or don't call this method and make sure the JNDI parameters are set.
     jmsServerManager.setContext(null);
     jmsServerManager.start();
     System.out.println("STARTED::");
  }
  catch (Throwable e)
  {
     System.out.println("FAILED::");
     e.printStackTrace();
  }
}
}
You can configure the server via the hornetq-configuration.xml file and configure any JMS objects via the hornetq-jms.xml file. Of course you can do much more than this with your server but this is a good starting point. Consult the HornetQ documentation for more information of what other features are available. client The client example shows how you can easily create a HornetQ JMS client using minimal jars. The dependencies this time are much smaller than the server and contain client jars that HornetQ provides for lightweight client apps.
   <dependency>
     <groupId>org.hornetq</groupId>
     <artifactId>hornetq-core-client</artifactId>
     <version>2.0.0.GA</version>
     <scope>compile</scope>
  </dependency>
  <dependency>
     <groupId>org.hornetq</groupId>
     <artifactId>hornetq-jms-client</artifactId>
     <version>2.0.0.GA</version>
     <scope>compile</scope>
  </dependency>
  <dependency>
     <groupId>org.hornetq</groupId>
     <artifactId>hornetq-transports</artifactId>
     <version>2.0.0.GA</version>
     <scope>compile</scope>
  </dependency>
  <dependency>
     <groupId>org.jboss.netty</groupId>
     <artifactId>netty</artifactId>
     <version>3.1.0.GA</version>
  </dependency>
  <dependency>
     <groupId>org.jboss.javaee</groupId>
     <artifactId>jboss-jms-api</artifactId>
     <version>1.1.0.GA</version>
     <scope>compile</scope>
  </dependency>
The client code in this case is copied from one of the HornetQ examples, running this client will send a message to the server that was started earlier.
public static void main(String[] args) throws Exception
{
   Connection connection = null;
   try
   {
       // Step 1. Directly instantiate the JMS Queue object.
       Queue queue = HornetQJMSClient.createQueue("exampleQueue");

       // Step 2. Instantiate the TransportConfiguration object which contains the knowledge of what transport to use,
       // The server port etc.

       Map connectionParams = new HashMap();
       connectionParams.put(PORT_PROP_NAME, 5445);

       TransportConfiguration transportConfiguration = new TransportConfiguration(NettyConnectorFactory.class.getName(),
                                                                                  connectionParams);

       // Step 3 Directly instantiate the JMS ConnectionFactory object using that TransportConfiguration
       ConnectionFactory cf = HornetQJMSClient.createConnectionFactory(transportConfiguration);

       // Step 4.Create a JMS Connection
       connection = cf.createConnection();

       // Step 5. Create a JMS Session
       Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

       // Step 6. Create a JMS Message Producer
       MessageProducer producer = session.createProducer(queue);

       // Step 7. Create a Text Message
       TextMessage message = session.createTextMessage("This is a text message");

       System.out.println("Sent message: " + message.getText());

       // Step 8. Send the Message
       producer.send(message);

       // Step 9. Create a JMS Message Consumer
       MessageConsumer messageConsumer = session.createConsumer(queue);

       // Step 10. Start the Connection
       connection.start();

       // Step 11. Receive the message
       TextMessage messageReceived = (TextMessage)messageConsumer.receive(5000);

       System.out.println("Received message: " + messageReceived.getText());
   }
   finally
   {
      if (connection != null)
      {
         connection.close();
      }
   }
}
You can use this template as a starting point for any projects you may want to create that would use HornetQ as a client or as an embedded server.

4 comments:

  1. Excellent blog! I am very glad to have found it.

    One question:

    In line 12, shouldn'r it be upper case letters in String and Object?

    ReplyDelete
  2. Hi, I tried to use your example in a project, but I'm getting java.lang.NullPointerException on this:

    configuration.setConfigurationUrl("hornetq-configuration.xml");

    I already put the file on classpath (Eclipse) and did not work. Any tip?

    Regards!

    ReplyDelete
  3. I there an update for this fine example available that uses HornetQ 2.1.1 ?
    Using the client against a 211 server (within JBoss EAP 5.1 CR) shows issues on the JBoss side, which look like the wire format may have changed

    17:42:45,843 ERROR [RemotingConnectionImpl] Failed to decode
    java.lang.IndexOutOfBoundsException
    at org.jboss.netty.buffer.AbstractChannelBuffer.readByte(AbstractChannelBuffer.java:236)
    at org.hornetq.core.buffers.impl.ChannelBufferWrapper.readNullableString(ChannelBufferWrapper.java:64)
    at org.hornetq.core.protocol.core.impl.wireformat.CreateSessionMessage.decodeRest(CreateSessionMessage.java:192)

    But just doing a s/2.0.0/2.1.1/ in the pom is not enough for me

    ReplyDelete
  4. For 2.1.1, see http://stephane.nicoll.net/2010/07/18/getting-the-necessary-libraries-to-run-a-hornetq-client/

    ReplyDelete