April 20, 2011, 6:17 p.m.
posted by franni
JMS API Basics
We certainly can't cover all of the ins and outs of using the JMS API in this chapter; that subject has filled entire books. Instead, we refer the interested reader to [Monson-Haefel] or [IBM-JMS] for the details of the API. Luckily, the API is based upon only a few simple concepts, which we can flesh out in the context of a very simple example. Once you understand this basic example you'll be in better stead to understand the more complete example presented later in the chapter.
As mentioned previously, the fundamental action of sending a message in JMS involves using a message producer to place a message on a destination. Let's first look at how these concepts are implemented in JMS and how you can use them in your programs.
The first concept we need to introduce is how to find a destination. Destinations are held in the JNDI namespace, just as EJBs are. The following syntax can be used (note that it is nearly identical to locating an EJB home interface).
InitialContext ctx = new InitialContext(); Object o = ctx.lookup("jms/QOrTopicName"); javax.jms.Queue aQueue = (javax.jms.Queue) java.rmi.PortableRemoteObject.narrow(o,javax.jms.Queue.class);
However, unlike an EJB, you can't just start using a Queue to send messages. Remember that you must have a Message producer to send messages—to create a message producer, you must first obtain a connection. In that respect, JMS is much more like JDBC. The syntax for obtaining a Connection is shown next:
//Look up the QueueConnectionFactory in JNDI Object o = ctx.lookup("jms/ivtQCF"); javax.jms.QueueConnectionFactory qcf = (javax.jms.QueueConnectionFactory) java.rmi.PortableRemoteObject.narrow(o, javax.jms.QueueConnectionFactory.class); //Create a QueueConnection javax.jms.QueueConnection conn = qcf.createQueueConnection();
Again, like in JDBC, you then need to obtain an object from a connection that you can work with. The JMS Session object is the transactional object that you use to create message producers. While the objects we've seen previously (Queues, Connection Factories, and Connections) are all thread-safe and can be shared across several threads of execution (and therefore cached), the Session must be created for each individual thread, and should always be closed at the end of its use.
//Create a QueueSession javax.jms.QueueSession session = conn.createQueueSession(false,javax.jms.Session.AUTO_ACKNOWLEDGE);
Now that you've created a Session, you're finally ready to create a message producer on the queue that we obtained in the first step:
javax.jms.QueueSender sender = session.createSender(aQueue);
Our example is nearly finished. We can now create a message and place it on a queue. In JMS, messages come in several flavors. TextMessages are messages whose body (or pay load) is a text string. There are also ObjectMessages that carry serialized Java objects, MapMessages that carry name/value pairs, ByteMessages, and StreamMessages. In our example, we'll use a TextMessage, which is probably the most commonly used message type:
// Create the Text Message Message message = session.createTextMessage(); message.setJMSType("LogMessage"); message.setText("Hello World"); //Send the message sender.send(message);
In this quick introduction to using JMS to send messages, we've omitted all of the exception processing that is necessary in a full example. We'll show that later in the chapter. We've also not covered receiving messages, which we'll cover later as well. However, this should serve as a good enough introduction to the concepts that you can understand the more complete examples presented later.