JMS – Advanced

JMS is the API which includes the MessageListener interface, the QueueSender, the QueueReceiver and a bunch of such objects that are useful for sending and receiving messages. There are a couple of configuration files for messaging. These configuration files contain name of queue, queuemanager, host name of MQ machine etc.(MQ is IBM’s brand of messaging middle-ware) which usually the administrator handles. The configuration files are tapped to get the Properties() for getting the sender and receiver objects -the lookup. So suppose you need to send a message you read configuration files with code similar to the one in the earlier post. The configuration file is used to get the Properties() object, including the name of the OUT queue – the queue you will be placing your message on for sending. For sending a message you need an OUT queue. Then you create a message

TextMessage message = new TextMessage("blahblah"); 
outQueue.getSender().send(message);

TextMessage is part of the JMS API. The message goes out the door and sending is complete.
In point to point(queue) communication discussed earlier the two points described are applications similar to webservices when one application (webservice client) communicates to another application (webservice server).
Example
Suppose our application is a loan processing system, the lender company uses the application to process loans for customers. So if the home lies in a flood prone area the customer needs flood insurance. We send a request on MQ to the flood insurance company’s system using messaging.When the flood insurance company is ready to respond, it sends us back a confirmation. When the app needs additional functionality when needed, and we don’t want to incorporate that stuff in our application, you do this by messaging. The messaging service provides that extra functionality. This message initiates another process in the flood insurance guy’s s/w app which has a message listener that listens to messages and populates their database. When the guy is ready to process and approve it, he may respond by sending a message back. This is two way listening when an application would be both a sender and receiver,but the transaction is asynchronous; the sender does not have to wait for the listener to respond – there’s no deadlock now.The client application is not held up for a response; it just places message on queue and forgets about it for the time being.
Let us move on to receiving messages.
For receiving a message you can write a java class which implements MessageListener interface by implementing it’s onMessage(Message m) method. Sending does not require any interface to be implemented; it requires only getting Properties() and through it, the sender object
For receiving a message you can write a java class which implements MessageListener interface. This method gets invoked when a message arrives on the IN queue.
So you read the message like this

String payloadString = ((TextMessage)m).getText();

The string may be xml in which case you can create a DOM object. Message is a a param to the onMessage method which could be a binary message or text message that you cast to correctly read it. You can also listen using MDB in which case you will implement MessageDrivenBean and MessageListener interfaces. Here also you will need onMessage method, that functions exactly the same way
Many senders can share a single OUT queue.
With point to point using queues:
sender app -> OUT queue -> IN queue -> receiver app
with a queuemanager managing the OUT and IN queues.
Only one receiver app can listen to the IN queue. Technically multiple receivers can listen – but can’t be sure which one is going to get the message. It’s a hit and miss, entirely unpredictable. Here if there are multiple receiver apps reading the IN queue – you can’t be sure which receiver app is going to get the message, so it’s not a good strategy to use multiple receiver apps.
When one receiver app picks up the message, the message is consumed, the other receiver app will not get anything. That’s why it’s NOT a good idea to have multiple receiver apps listening to an IN queue, even though it is technically possible.
But in case of one to one, its always one sender and one listener to the IN que. In case of one to one
one sender -> OUT queue -> IN queue -> one receiver
Now technically one can have many senders
many sender -> OUT queue -> IN queue -> one receiver
There is no problem with that, so that many apps can get the service of a listener app.
But 99% cases are
one sender -> one receiver
If there are many senders, all these share the same OUT configured in the xml file.
Each application has its own config files to tell it the names of the queue etc.
Queue names,queuemanager name, host name, port are typically part of the configuration.
In case of Topics
one sender -> Topic -> multiple receivers
Here the difference is, there can be multiple receivers which will all receive the message because the messages are not “consumed” only by one receiver.
A Topic is the equivalent of a queue – the difference is that it is one to many, and the message is NOT CONSUMED. The messages are available for a moment and then vanish into thin air. They are not guaranteed to be delivered to any receiver, rather like a news broadcast or radio broadcasts and not even one reciever may get the message sometimes. It is not used much but could be useful for broadcasting news or such.

JMS and Message Driven Beans – Introduction

MDBs are the third kind of EJBs among Session, Entity and Message-driven beans, and was introduced in EJB2.0. It uses the Java Messaging Service protocol for communicating.
MDB is all about JMS. JMS and MDBs go together, like bread and butter.
MDBs are used for communicating using JMS protocol which is Java’s messaging API.
There are two types of messaging: Queues and Topics. Queue is one-to-one whereas Topic is one to many. A message could be some text or xml document or binary object; usually it is an xml document.
The senders and recievers may or may not be Java objects. In case Java is the software, it would be Java objects using JMS API.
For example, it could also be C++ using some other API, on the other hand it could be COBOL.
In the case of MDBs, it is Java on one side, and may be any legacy s/w on the other end. Messaging is sometimes used to communicate with legacy mainframes as well. In other words Messaging protocol can be used with non Java environments; but if you are using the JMS API then you are using Java for messaging.
Similarly C++ would have its own API for messaging, and COBOL its own API.
There are two types of Messaging:
1 Point to Point (using Queues)where you have one sender and one receiver. Delivery is guaranteed and the message does not get lost but is delivered to the receiver. Queues are first in first out. Sender places message1 and then message2 in queue – these get delivered in FIFO order to receiver.
2 One to Many The second type of messaging is one to many (using Topics) where there is one sender sending messages to many receivers. Sender sends the message and doesn’t care who is receiving. Receivers may or may not listen. Delivery is not guaranteed; it is upto the receiver to listen.
One-to-many (using Topics) messaging is almost never used.
Let us focus on Queues – one to one messaging.
The queue is controlled by the queuemanager which can retry sending a message many times to make sure receiver gets it. If queuemanager is unable to deliver, the message ends up in the dead letter queue – which is a like the Dead Letter Office of a post office for a letter without an address. A message delivery may fail if the delivery endpoint is not running the receiver.
Messaging enables asynchronous communication where the sender does not have to care whether receiver is running or not. The sender places the message on the queue with the assurance that queuemanager will deliver it. So it’s not upto the sender but the queue manager to see to it that the message is not lost even in one to one messaging. The sender just places the message on queue. This helps in decoupling the dependency of disparate systems by making it asynchronous.
What do you mean by the term asynchronous?
HTTP is synchronous. If one system does an HTTP POST to a server it is a synchronous transaction. Both systems depend on each other to work together in processing request and response. But messaging is asynchronous. There is some decoupling between sender and reciever. The sender doesn not care for the reciever, the queue acts as the broker between two systems like a middeware. Messaging is just a protocol like HTTP with some differences. You can send text, xml, html, binary data as a message. It is rather an asychronous messaging protocol where the sender does not couple directly with the receiver.
Back to trivia: Any non-Java system can use the messaging protocol similar to how Java systems do viz. ASP for instance, can use the HTTP protocol. So dotNet would have have its own API for messaging where there would be an equivalent asynchronous protocol.
Now to MDBs.
In Java, if you wish to use the HTTP protocol you would typically write a Servlet class. Similary, in Java, if you wish to use Messaging protocol you would write an MDB (or another option would be to use a plain Java class that implements MessageListener interface). Http sends text or binary data from html to servlet and similary JMS sends text/binary to/from sender/reciever with queue manager handling the process. The sender and reciever do not have to be on same JVM. Sender and receiver can be miles apart; we concern ourselves with JMS only from the sender and receiver point of view.
JMS is the programming language equivalent of a technology like HTTP. JMS is the programming API for messaging similar to how the Servlet API is the programming API for HTTP but asynchronous. In the servlet API – you have request and response objects; in the JMS API – you have sender and receiver objects.
Practical aspects: You can use messaging instead of HTTP, HTTP is also a kind of messaging.
Its an architectural decision to choose the protocol: the advantage of JMS is asynchronous behaviour; some things can be done asynchronously. There is no direct coupling between sender/ reciever- asynchronous means sender and receiver don’t have to be in tandem, they do not have to work together; sender is not blocked because of receiver.
HTTP is useful when two systems talk in request-response(two-way) fashion. However sometimes communication is only one-way.
Why does an EJB bean have to handle JMS as in MDB?
You don’t need an EJB to handle JMS, same as you don’t need an EJB to write business logic or to write JDBC. EJB is optional. If you are using EJB, that would be an MDB. We could use regular java classes that implement MessageListener interface. Session beans and entity beans allow you to send JMS messages and to receive them synchronously, but not asynchronously. To avoid tying up server resources, you may prefer not to use blocking synchronous receives in a server-side component. To receive messages asynchronously, use a message-driven bean. An MDB is not be terribly different from java class implementing the MessageListener interface.
Some sample code:

Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, context.getInitialContextFactory());
env.put(Context.PROVIDER_URL, context.getProviderUrl());
env.put(Context.REFERRAL, "throw");
InitialContext jndiContext = new InitialContext(env);
factory = (QueueConnectionFactory) jndiContext.lookup(context.getQueueConnectionFactory());
inQueue = (Queue) jndiContext.lookup(context.getInQueue());
outQueue = (Queue) jndiContext.lookup(context.getOutQueue());
connection = factory.createQueueConnection();
session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
receiver = session.createReceiver(inQueue);
sender = session.createSender(outQueue);

Basically at the end of the code, you get a receiver and sender object which are like the javax.servlet.ServletRequest and javax.servlet.ServletResponse objects of HTTP.
In the above snippet the application is BOTH a sender a receiver. The application (sender A) talks to another application (receiver B). The other application (sender B) talks to the first application (receiver A). There could be a two way communication – without it being request-response .In this case it’s a two way street, but we could do with just the sender object in app A and a reciever in app B.
Applications send and recieve messages. The case is always app to app; there is no browser. Here, it is similar to how app to app communication happens over HTTP for web service.