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)

Application testing using embedded brokers (Advanced)


In this recipe we are going to look at how you embed an ActiveMQ Broker right into your own applications.

Getting ready

For this recipe we will use the example application named embedded-broker to demonstrate embedded ActiveMQ Brokers. Before proceeding, you should ensure that there are no other broker instances running on your computer.

How to do it...

To run the sample for this recipe, open a terminal, change the path to the directory where embedded-broker is located, and run it by typing mvn compile exec:java.

In the terminal where you started the example, you will see output similar to the following snippet indicating that the application is running:

Starting the Embedded Broker example now...
We sent a Message!
Finished running the Embedded Broker example.

How it works...

The output of the example in this recipe certainly doesn't look very impressive; what is impressive though is that we didn't have to run a separate broker in order for our example code to work. Because ActiveMQ is a pure Java application, it can easily be embedded into our messaging applications, which can be useful not only in our applications but also for testing application code in continuous integration suites.

In order to embed the broker into our sample application, we first had to add some additional dependencies to our Maven POM file. When embedding brokers, you need to include the following code in your POM file:

    <dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-broker</artifactId>
      <version>5.8.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-kahadb-store</artifactId>
      <version>5.8.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-spring</artifactId>
      <version>5.8.0</version>
    </dependency>

These additional libraries bring in everything we need to run a standard broker instance inside our example. Let's look at what each brings to the project:

  • <activemq-broker>: As you might have guessed, this is where the core of the ActiveMQ Broker implementation resides. This is required any time you want to embed a broker in your application.

  • <activemq-kahadb-store>: This library is the home of the default persistence adapter in ActiveMQ. You need to bring this in to use any of the default configurations.

  • <activemq-spring>: This library brings in the code necessary to create a broker instance from an XML configuration file, be it a pure Spring file or the XBean-based configuration files that ship with ActiveMQ. This could also be omitted if you create the broker using pure Java code; we'll look at that a bit later.

There are of course other dependencies that might need to be brought into your project depending on what broker features you use; these are just the top three. ActiveMQ does provide a single, all-encompassing library named <activemq-all> that can be included in your Maven POM file. This is useful but does mean your application will acquire a lot of extra dependencies that you will never actually use.

Our sample application consists of the code from our first recipe, Installing ActiveMQ (Simple), modified to create a broker directly in the code. Let's take a look at the code:

public class EmbeddedSimpleJMS {

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

    public void before() throws Exception {

        service = BrokerFactory.createBroker("xbean:activemq.xml");
        service.start();

        connectionFactory = new ActiveMQConnectionFactory(connectionUri);
        connection = connectionFactory.createConnection();
        connection.start();
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = session.createQueue("MyQueue");
    }

    public void after() throws Exception {

        if (connection != null) {
            try {
                connection.close();
            } catch (Exception ex) {}
        }

        if (service != null) {
            try {
                service.stop();
            } catch (Exception ex) {}
        }
    }

    public void run() throws Exception {

        MessageProducer producer = session.createProducer(destination);
        try {
            TextMessage message = session.createTextMessage();
            message.setText("We sent a Message!");
            producer.send(message);
        } finally {
            producer.close();
        }

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

In the application's before() method, we use the class BrokerFactory to create ActiveMQ's BrokerService object, which is really an ActiveMQ Broker. The BrokerFactory class allows us to pass a configuration file that should be used to configure the newly created broker; in our case, we added a very basic ActiveMQ XML configuration file to our Maven project's src/man/resources directory so that it would automatically be added to the classpath. When the application shuts down, it must stop its BrokerService object, which we do in the after() method after we close our connection.

As you can see, it's extremely simple to embed ActiveMQ right inside your application. In ActiveMQ, we make use of this feature to write all of the unit tests for the project; each test creates a broker in its setup code and then shuts it down after the test has run. This is something you can use in your own application tests to ensure your code is using a broker instance with the correct configuration and a known state, without having to use any external tools.

There's more...

Our simple sample application created a broker using the BrokerFactory class and a configuration file. If, however, we just want to create a simple BrokerService instance without the need for a configuration file or dependency on the Spring library, we can create one using pure Java. To do this, we just need to create an instance of BrokerService and configure it according to our project's needs. The Java code to create a broker equivalent to the one we created in our example would be:

BrokerService broker = new BrokerService();
broker.addConnector("tcp://localhost:61616");
broker.start();

Here, we instantiate a BrokerService instance and add the connector for the TCP-based transport that our client connects to; everything else we leave at the broker's defaults. We could, if we want to, go one step further and disable persistence so that our sample doesn't need to pull in the <activemq-kahadb-strore> library in our project POM. The code for that would be:

BrokerService broker = new BrokerService();
broker.addConnector("tcp://localhost:61616");
broker.setPersistent(false);
broker.start();

When using embedded ActiveMQ Brokers, people general try to look for a way to restart the broker. There is no restart method or other facility in the BrokerService class to do a safe restart, so users are often tempted to call stop() followed by a call to start() later on, but this won't work. The correct method of restarting a BrokerService instance is shown in the following code snippet:

broker.stop();
broker.waitUnitStopped();
broker = new BrokerService();
broker.addConnector("tcp://localhost:61616");
broker.start();

Where to find more about configuring embedded brokers

More information on the options available when using an embedded broker can be found on the ActiveMQ website, http://activemq.apache.org/how-do-i-embed-a-broker-inside-a-connection.html.