Fun with JMS

2 AM June 17, 2004

I've been investigating Java Message Service (JMS) over the last few days. I had been under the impression that it was an arcane, difficult to use API, but and pleasantly surprised when I actually started to use it. Here is some code to illustrate how easy it is.

A JMS program needs two objects before it begins: a QueueConnectionFactory and a Queue. Typically the program would look these up via JNDI, but the JMS products I've looked at (Sun Java System Message Queue1 and Websphere MQ) also allow them to be created 'by hand.'

The program asks the ConnectionFactory for a Connection, and then asks the connection for a session:


import javax.jms.*;



public class MQTest {



    public static final String QUEUE_NAME = "AQueueName";

    private QueueConnectionFactory qcFactory;

    private QueueConnection qConnection;

    private QueueSession qSession;

    private Queue queue;



    public void init() throws JMSException {

        qcFactory = new 

            com.sun.messaging.QueueConnectionFactory();

        qConnection = qcFactory.createQueueConnection();

        qSession = qConnection.createQueueSession(false, 

            Session.AUTO_ACKNOWLEDGE);

        queue = new com.sun.messaging.Queue(QUEUE_NAME);

    }

}

(The com.sun.messaging class is an implementation class from Sun's Java System Message Queue product.2)

A sending program also needs a sender object and a message object, both of which it obtains from the session. When it is time to perform the send, the program loads up the message object with data, and sends it:


    public void send(String msg) throws JMSException {

        init();

        QueueSender qSender = qSession.createSender(queue);

        TextMessage textMsg = qSession.createTextMessage();

        textMsg.setText(msg);

        System.out.println("Sending Message: [" + msg + "]");

        qSender.send(textMsg);

        close();

    }

In a real program, the QueueSender would be created once and reused.

To receive a message, a program uses a Receiver object, which it gets from the session. The receive() method waits for a message to be delivered and returns it:


    public void receive() throws JMSException {

        init();

        QueueReceiver qReceiver = qSession.createReceiver(queue);

        qConnection.start();

        TextMessage msg = (TextMessage) qReceiver.receive();

        System.out.println("Contents:" + msg.getText());

        close();

    }

Before receiving a message, the connection also needs to be informed that messages can be sent through it, by calling the start() method.

This is how to close connections and release any external resources. Be careful about this - some brands of messaging queuing middleware won't automagically clean up after a closed (or crashed) application.


    public void close() throws JMSException {

        if (qSession != null) {

            qSession.close();

        }

        if (qConnection != null) {

            qConnection.close();

        }

    }

And for completeness, here is a driver method for the above class:


    public static void main(String args[]) {

        try {

            if ("send".equals(args[0]))

                 (new MQTest()).send(args[1]);

            else if ("receive".equals(args[0]))

                 (new MQTest()).receive();

        } catch (JMSException e) {

            e.printStackTrace();

        }

    }

As you can see, this is not a lot of code to send a simple messages point to point. Even with some error handling code and a JNDI look up, it is still less programming effort than building a one-way, asynchronous message sending component out of TCP sockets or servlets.


1 A big thanks to Craig Day of the ajug mailing list for pointing me to Sun's product. The code here is a very much mangled version of Sun's tutorial code.

2 If you want to avoid any JMS product dependencies, then you need to use JNDI, though that creates other product dependencies.

By alang | # | Comments (0)
(Posted to javablogs and Java)

Comments

Add Comment




(Not displayed)






(Leave blank line between paragraphs. URLs converted to links. HTML stripped. Indented source code will be formatted with <pre> tags.)




© 2003-2006 Alan Green