Book Image

Instant Apache ActiveMQ Messaging Application Development How-to

By : Timothy A. Bish
Book Image

Instant Apache ActiveMQ Messaging Application Development How-to

By: Timothy A. Bish

Overview of this book

Apache ActiveMQ is a powerful and popular open source messaging and Integration Patterns server. ActiveMQ is a fully JMS 1.1 compliant Message Broker and supports many advanced features beyond the JMS specification.Instant ActiveMQ Application Development How-to shows you how to get started with the ActiveMQ Message Broker. You will learn how to develop message-based applications using ActiveMQ and the JMS specification. In this book you will learn all the basic skills you need to start writing Java Messaging applications with a firm grounding in the more advanced features of ActiveMQ, giving you the tools to continue to master application development using ActiveMQ. Starting by applying the messaging features of the JMS specification to write basic messaging applications, you will develop a basic JMS application using topics and queues to broadcast events as well as perform Request and Response operations over the JMS. Once you have mastered the simple tasks you will move onto using the advanced features in ActiveMQ to supercharge your messaging applications. You will get to grips with ActiveMQ's scheduler to delay messages. You will also learn how to leverage ActiveMQ's fault-tolerant capabilities to create robust client applications.
Table of Contents (7 chapters)

Creating ActiveMQ applications (Simple)


In this recipe we are going to create a very simple JMS application that places a message on a queue in ActiveMQ and consumes that message from the queue immediately after. This example demonstrates many of the JMS APIs that we will be using in the future recipes.

Getting ready

In this recipe, we will be referencing the simple-jms-application project that contains the full working code and Maven POM file. You should have a default installation of the ActiveMQ Broker running before attempting to execute the sample application in this recipe.

How to do it...

To run the sample for this recipe you will need to perform the following steps:

  1. Open a terminal and start an instance of the ActiveMQ Broker.

  2. Open a second command-line window, change to the directory where the simple-jms-application project is located, and execute the following command:

    mvn compile exec:java
    

This will build and run the sample application and you should see an output similar to the following, assuming everything goes well:

INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------
[INFO] Building Simple-JMS-Application 1.0
[INFO] ------------------------------------------------------------------
[INFO] 


Starting SimpleJMS example now...
Producer sent a Message
Consumer received a Message, it reads: Woohoo!
Finished running the SimpleJMS example.


[INFO] ------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------
[INFO] Total time: 1.249s
[INFO] Finished at: Mon Feb 25 17:19:30 EST 2013
[INFO] Final Memory: 6M/265M
[INFO] ------------------------------------------------------------------

How it works...

Now that we've run the example, let's take a look at the code and see how it works. The complete source code is located in the file SimpleJMS.java in the example simple-jms-application. You are encouraged to open the file and refer to it during this discussion.

This example defines three methods: before(), run(), and after(), which we call in sequence. Each of these methods breaks out the basic steps you must do in any JMS application:

public class SimpleJMS {

    private final String connectionUri = "tcp://localhost:61616";
    private ActiveMQConnectionFactory connectionFactory;
    private Connection connection;
    private Session session;
    private Destination destination;

    public void before() throws Exception {
        connectionFactory = new
            ActiveMQConnectionFactory(connectionUri);
        connection = connectionFactory.createConnection();
        connection.start();
        session = connection.createSession(
            false, Session.AUTO_ACKNOWLEDGE);
        destination = session.createQueue("MyQueue");
    }

In the before() method we set up our connection to the ActiveMQ Broker and create the basic JMS boilerplate objects that we'll use in the run() method later. The setup here proceeds as follows:

  1. Create a new JMS ConnectionFactory using the concrete type ActiveMQConnectionFactory, which is provided in the ActiveMQ client library. The ConnectionFactory is supplied the URI of our running broker, namely, tcp://localhost:61616. Every ActiveMQConnectionFactory needs a URI telling where and how to connect to the broker.

  2. Create a new JMS Connection object by invoking the ConnectionFactory object's createConnection method. If the connection to the broker cannot be created we will get an exception at this point.

  3. We can now start our new Connection. A JMS Connection object won't deliver any messages to your MessageConsumer until you start it so it's very important to remember to call connection.start().

  4. Create a new JMS Session object by calling the Connection object's createSession() method. Since Session requires a message acknowledgement mode, we specify that in the createSession() method. We choose auto acknowledgement mode so we don't have to worry about manually acknowledging messages in this simple application.

  5. Finally we create a Destination object that our application's producer and consumer will use to send and receive our simple message. In our example we create a queue but it would work exactly the same if we had used a Topic domain for this simple example.

Once the before() method completes, our little application is ready to go; so we next call the run() method to do the work. The code for the run() method is shown next:

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

    public void run() throws Exception {
        MessageProducer producer =
            session.createProducer(destination);
        try {
            TextMessage message = session.createTextMessage();
            message.setText("Woohoo!");
            producer.send(message);
        } finally {
            producer.close();
        }

        MessageConsumer consumer =
            session.createConsumer(destination);
        try {
            TextMessage message = 
                (TextMessage) consumer.receive();
        } finally {
            consumer.close();
        }
    }

This method is divided into two parts, one of which performs the send of our simple message and then our attempts to receive it. Let's break down the send portion first:

  1. Using the Session we created earlier, we first create a MessageProducer; this is the object that will allow us to send our simple message.

  2. Create a new TextMessage object using the Session object and assign it a payload at the same time.

  3. Send the message using the MessageProducer object's send() method. The MessageProducer object knows where to send the message since we passed in a Destination object when we created it.

  4. Finally, we close down the MessageProducer object since we won't use it again in this application.

Now that we've seen how a message is sent, we can look at how receiver code works:

  1. First we create a MessageConsumer object using Session just as we did for the MessageProducer previously

  2. We use the MessageConsumer object blocking the receive() call to wait for the broker to route the message we sent previously to our producer

  3. Once we receive the message we need to cast it to the correct type since the receive() method returns a base message reference

  4. We print out a little message showing the payload of the TextMessage we sent previously

  5. Finally, we close down our consumer since we are done with that as well

All that's left is to call the after() method, which simply closes the Connection object we opened in the before() method and our application comes to an end.

    public void after() throws Exception {
        if (connection != null) {
            connection.close();
        }
    }

Closing Connection will take care of closing out any resources created by the connection, so we omit the call to the close() method of our Session.

This simple application demonstrates many of the elements of the JMS API that you will use in the messaging applications that you write in the future. Unlike our future examples this one incorporates both a producer and consumer within the same application. In our future examples, we will generally break apart the producer and consumer into separate applications for a more realistic demonstration.

There's more...

Before we move onto the remainder of the examples in this book, it's a good idea to understand the Maven project files that build and run our projects. A Maven POM file defines the various modules of a project and allows us to specify all the required libraries we need to be assembled in order for our project to run. Maven also allows for various plugins to be specified in the POM file that can perform actions beyond just compiling code and downloading dependencies. Let's take a look at the POM file that we used to run our first application, it's located in the directory of our simple-jms-application example:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>org.apache.activemq.recipes</groupId>
  <artifactId>SimpleJMS</artifactId>
  <version>1.0</version>
  <name>Simple-JMS-Application</name>
  <description>A simple JMS application</description>

  <dependencies>
    <dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-client</artifactId>
      <version>5.8.0</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.2</version>
    </dependency>
  </dependencies>

</project>

As you can see, the POM file is just a basic XML file with sections for project dependencies and a section for specifying the plugins used in the build process.

Take note of the dependencies that we specified in our SimpleJMS application's POM file. We only needed to bring in the <activemq-client> dependency and a log4j plugin so that the ActiveMQ client knows what logger our project is using. Maven figures everything else out for us so that we don't have to fuss with classpath issues and just focus on our ActiveMQ skills. It's good to get an idea of how Maven works if you haven't used it already as it can greatly streamline your build process.

A brief aside on Connection URIs

In our SimpleJMS application we created a connection to the ActiveMQ Broker by creating an instance of ActiveMQConnectionFactory and giving it a URI string that told it how to connect to ActiveMQ. We used the string, tcp://localhost:61616 in our example, which tells the client that it should use a TCP-style connection to connect to the broker on port 61616. ActiveMQ supports a number of different connection options beyond TCP such as SSL, HTTP, NIO, and more. You can get more information on how to use those connection types and on configuration options that can be added to the URI string on the ActiveMQ website, the following links provide an overview of the connection URI configuration syntax and options: