JMS API Programming Model

JMS API Programming Model

JMS (Java Message Service) is a Java API that allows applications to create, send, receive, and read messages. The JMS API enables communication that is not only loosely coupled but also:

  • Asynchronous. A JMS provider can deliver messages to a client as they arrive; a client does not have to request messages in order to receive them.
  • Reliable. The JMS API can ensure that a message is delivered once and only once. Lower levels of reliability are available for applications that can afford to miss messages or to receive duplicate messages.

In this article, we will use ActiveMQ as JMS provider. ActiveMQ is an open sourced implementation of JMS API 1.1 as part of the J2EE 1.4 specification. You can download ActiveMQ from this link. After the download, extract it to any directory and run the ‘activemq’ (for Linux) or ‘activemq.bat’ (for Windows) from beneath the ‘{path-where-you-extracted-activemq}/bin’ directory.

ActiveMQ up and running

ActiveMQ up and running

Image above (I’m using Windows 8) show that ActiveMQ is up and running. You can close it any time by pressing Ctrl-C. ActiveMQ has a nice admin console, where you can see a lot of useful informations and change the settings: http://localhost:8161/admin/. (user/pass: admin/admin).

Now that we have a JMS provider running, let’s write our message producer and consumer programs. Oh wait. What is Producer? And what is Consumer? Producer is a Java program sending a JMS message to a Queue on the JMS Provider. Consumer is another program which receives that message. These two programs can run on separate machines and all they have to know to communicate is the URL of the JMS Provider. But in this article, we will run Producer and Consumer on same machine with JMS Provider (at  localhost).

Now, here is the sample code of the program that sending (or producing) the messages.

import javax.jms.*;


import org.apache.activemq.ActiveMQConnectionFactory;

public class Producer {
    // URL of the JMS server. 61616 is JMS default port
    private static String url = "tcp://localhost:61616";

    // Name of the queue we will be sending messages to
    private static String subject = "QUEUENAME";

    public static void main(String[] args) throws JMSException {
        // Create Connection Factory
        ConnectionFactory connectionFactory =
            new ActiveMQConnectionFactory(url);
        Connection connection = connectionFactory.createConnection();
        connection.start();

        // Create Session. JMS messages are sent and received
        // using a Session.
        Session session = connection.createSession(false,
            Session.AUTO_ACKNOWLEDGE);

        // Destination represents here our queue 'QUEUENAME' on the
        // JMS server.
        Destination destination = session.createQueue(subject);

        // Create Message Producer
        MessageProducer producer = session.createProducer(destination);

        // We create the Message to be send. There are
        // many types of Message. TextMessage is just one of them
        TextMessage message = session.createTextMessage("Hello from JMS");

        // Here we are sending the message!
        producer.send(message);
        System.out.println("Sent message : '" + message.getText() + "'");

        connection.close();
    }
}

Now, let’s see how to receive (consume) the message. Here is the sample code for the Consumer class.

import javax.jms.*;


import org.apache.activemq.ActiveMQConnectionFactory;

public class Consumer {
    // URL of the JMS server
    private static String url = "tcp://localhost:61616";

    // Name of the queue we will receive messages from
    private static String subject = "QUEUENAME";

    public static void main(String[] args) throws JMSException {
        // Create Connection Factory
        ConnectionFactory connectionFactory
            = new ActiveMQConnectionFactory(url);
        Connection connection = connectionFactory.createConnection();
        connection.start();

        // Create session
        Session session = connection.createSession(false,
            Session.AUTO_ACKNOWLEDGE);

        // Getting the queue 'QUEUENAME'
        Destination destination = session.createQueue(subject);

        // MessageConsumer is used for receive (consume) messages
        MessageConsumer consumer = session.createConsumer(destination);

        // Receive the message. By default this call
        // is blocking, which means it will wait for
        // a message to arrive on the queue.
        Message message = consumer.receive();

        // Consumer must know type of message. In Producer
        // above, we use TextMessage
        if (message instanceof TextMessage) {
            TextMessage textMessage = (TextMessage) message;
            System.out.println("Received message : '"
                + textMessage.getText() + "'");
        }else{
            System.out.println("Runtime Error: Unsupported type of message");
        }
        connection.close();
    }
}

Consumer’s code is pretty similar to the Producer’s code before. The different is on Producer class line 30, we create Producer, while in Consumer class line 29, we create Consumer. Don’t forget to adding ActiveMQ’s JAR file to the classpath. Compile now, and then run Producer first.

Producer Sent a Message

Producer Sent a Message

If you see something similar to the output above it means that the message was successfully sent and is now inside the QUEUENAME queue. You can enter the Queues section in the ActiveMQ’s admin console http://localhost:8161/admin/queues.jsp and see that there is one message sitting in QUEUENAME:

ActiveMQ Message Enqueued

ActiveMQ Message Enqueued

If you are getting above input (or something similar) everything went OK. The message was successfully received. Now, run the Consumer.

Consumer receive message

Consumer receive message

Now refresh ActiveMQ’s admin console on the browser.

ActiveMQ Message Dequeued

ActiveMQ Message Dequeued

Now you see that the message has been dequeued. You can download JMS full tutorial from here.