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.

About cuppajavamattiz
Matty Jacob - Avid technical blogger with interests in J2EE, Web Application Servers, Web frameworks, Open source libraries, Relational Databases, Web Services, Source control repositories, ETL, IDE Tools and related technologies.

Comments are closed.

%d bloggers like this: