JavaData & JavaGetting Started with MOM in JMS

Getting Started with MOM in JMS

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

MOM (Message Oriented Middleware) is basically an infrastructure to support communication between software components and applications and JMS (Java Messaging System) is the implementation of the model in Java. JMS is loosely coupled and inherently asynchronous but enterprise components, such as EJB, commonly use synchronous calls to remote components (of course, unless @Asynchronous annotation is used). MOM enables asynchronous message sending and receiving between distributed systems. It acts like a buffer in between systems from where message producer/publisher and consumer/subscriber get their raw feed. JMS is the Java EE API that deals with the concept of MOM and helps in creating the enterprise messaging system to produce and consume asynchronous messages.

JMS Messaging

The messaging infrastructure of JMS is quite simple; the application component that sends a message is called a message producer or publisher and the recipient component that retrieves the message is called a consumer or subscriber. In between is the middleware, JMS server, which acts a mediator and is called a provider or a broker. Now, messages can be sent to either two types of destinations. One can be called a queue-model another a topic-model. These two types of destinations actually form the basic building block of the messaging model of JMS namely, Point-to-point and Publish Subscribe.

At very high-level, messaging architecture comprise the following elements.

    • Connection Factory: The javax.jms.ConnectionFactory interface is an administered object, which provides connection configuration parameters and is used for creating a connection with the JMS provider. This hides the provider specific information from the JMS client and abstracts the administrative information into Java objects. The client uses JNDI look up or injection to use this ConnectionFactory object.
       Context jndiContext = new InitialContext();    
       ConnectionFactory connectionFactory = (ConnectionFactory) jndiContext
                                  .lookup("jms_conn");
    • Destination: The destination object provided by javax.jms.Destination interface is also an administered object that defines the target of the message. It acts like an address where messages are dispatched and later on the consumer retrieves. In the case of the P2P model this destination is called the queue and in the Pub-sub model it is called the topic.
       Context jndiContext = new InitialContext();
       Destination queue = (Destination)jndiContext   .lookup("jms_conn_queue");
    • Connection: A connection provided by javax.jms.Connection is used to create a virtual connection of the TCP/IP socket between a JMS client and the service provider and is responsible for creating one or more sessions. The sessions object, provided by javax.jms.Session, is a single threaded context used for creating messages, creating producers and consumers and serializing all the transactional aspects of the message interchange.
      Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);

Start/stop methods of Connectioncan be used to temporarily pause receiving messages without closing the connection with the close method.

      Connection connection = connectionFactory.createConnection();
  • Provider: Provider aka broker is the router responsible for buffering and delivery of messages, JMS is the API to create MOM infrastructure in Java.
  • Client: The client can be any JEE application component that either produces or consumes messages from the provider. The ‘client’ is actually a generic term used to denote both consumer/subscriber and producer/publisher.
  • Message: These are nothing but Java objects created by the producer and received by the consumer; the middleware responsible for the send and receive of the message is the provider. A message comprises three parts, a header, properties and the body. The header contains metadata to uniquely identify a message and route them properly. The properties provide a provision to include additional information to the header and data contains the content of message in different formats such as text, stream, map object or byte.

Messaging Model of JMS

JMS API supports two types of messaging models:

1.Point-to-point (P2P) model: In P2P, the model message publisher creates the message to be subscribed by a single consumer, i.e. destination is specified. The message, once published is held in the message queue of the provider until it’s dispatched. The subscriber who first fetched the message gets it and once it’s dispatched others cannot get it. When the subscriber receives the message, an acknowledgment is sent to the provider. On receiving the acknowledgment, the message is removed from the queue. Thus P2P is a queue based model, which acts like a buffer for message dispatch.

 Point-to-point (P2P) model

2.Publish-Subscribe (Pub-Sub) model: The Pub-Sub messaging model is topic based and the message is broadcast to all consumers who subscribe (registered to receive) that particular topic. Each topic has a unique identity defined by the messaging server. So, typically, the destination here is the topic itself and consumers are multiple JMS clients.

 Publish-Subscribe (Pub-Sub) model

An Example

There are several ways to implement MOM in JMS as the intricacies of configuration in creating one varies from app server to app server. Given below is a very simplistic code to create a message producer, however, to get the step by step details of on how to configure JNDI, message queues etc. refer to oracle.com‘s JMS tutorial.

index.xhtml

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html  
      xmlns_h="http://xmlns.jcp.org/jsf/html"> 
    <h:head> 
        <title>MOM Demo</title> 
    </h:head> 
    <h:body>        
        <h:form> 
            <h:outputLabel value="Type something " for="message"/> 
            <h:inputText id="message" value="#{producerBean.message}"/> 
            <h:commandButton value="Send" action="#{producerBean.send()}"/> 
        </h:form> 
    </h:body> 
</html>
 
//...import statements
 

ProducerBean.java

 
@Named(value = "producerBean") 
@RequestScoped 
 
public class ProducerBean { 
 
    @Resource(mappedName = "jms/myQueue") 
    private Queue myQueue; 
    @Resource(mappedName = "jms/myQueueFactory") 
    private ConnectionFactory myQueueFactory; 
 
    private String message; 
 
    public MessageProducerBean() { 
    } 
 
    public String getMessage() { 
        return message; 
    } 
 
    public void setMessage(String message) { 
        this.message = message; 
    } 
 
    public void send() throws JMSException { 
        FacesContext facesContext = FacesContext.getCurrentInstance(); 
        sendJMSMessageToMyQueue(message); 
        FacesMessage facesMessage = new FacesMessage("Message sent: " + message); 
        facesMessage.setSeverity(FacesMessage.SEVERITY_INFO); 
        facesContext.addMessage(null, facesMessage); 
    } 
 
    private Message createMessageFormat(Session session, Object messageData) throws JMSException { 
        TextMessage textMessage = session.createTextMessage(); 
        textMessage.setText(messageData.toString()); 
        return textMessage; 
    } 
 
    private void sendJMSMessageToMyQueue(String messageData) throws JMSException { 
        Connection connection = myQueueFactory.createConnection(); 
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 
        MessageProducer messageProducer = session.createProducer(myQueue); 
        messageProducer.send(createMessageFormat(session, messageData)); 
 
        if (session != null) { 
            session.close(); 
        } 
        if (connection != null) { 
            connection.close(); 
        } 
    } 
} 

Conclusion

Message driven beans have a significant advantage over traditional JMS clients as it has the ability to consume and process messages concurrently. Developers can focus on the business logic of the processing rather than being busy in building a custom JMS client for managing resources, transaction and security in the multithreaded environment. Message transaction in other tightly coupled technologies such as RMI or HTTP is significantly different from JMS. In JMS, Message Server acts as a mediator of conversation between message producer and the consumer so strictly speaking it is not a peer to peer conversation like RMI or HTTP. Secondly, the message producer and the consumer must know about the message format and what destination to use while RMI requires knowing only about the remote application methods. However, with all its pros and cons, JMS is still quite suitable for implementing MOM and can be used efficiently to create one by the developer without any doubt.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories