ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

A Java Message Service Primer
Pages: 1, 2, 3

In order to receive messages in an asynchronous manner a message listener needs to be created and register one or more implementations of the JMS MessageListener interface with the MessageConsumer. The Session (Topic or Queue) is responsible for making certain messages are passed to the listener by calling the onMessage method.



import javax.jms.*;

public class ExampleListener implements MessageListener {

    //Cast the message to a TextMessage 

    public void onMessage(Message message) {
        TextMessage textMsg = null;
           
                // unpack and handle the message
    }
}

When we create our QueueReceiver and TopicSubscriber, we pass in the message selector String:

//P2P QueueReceiver 
QueueReceiver receiver;
receiver = session.createReceiver(queue, selector);

//Pub-Sub TopicSubscriber 
TopicSubscriber subscriber;
subscriber = session.createSubscriber(topic, selector);

To start the delivery of messages, whether Pub/Sub or P2P, the required start method is called.

TopicConnection.start( ); //pub-sub

QueueConnection.start( ); //P2P

When a message is consumed, the message arrives as a generic Message object that must be cast to the appropriate message type. This is a getter method that is used to extract or otherwise unpack the message contents. The following code fragment uses the StreamMessage type.

private void unPackMessage (Message message) {
        
   String eName;
   String position;
   double rate;
   StreamMessage message;

   Message = session.createStreamMessage( );
        
   //note the following must be written in the order 
//in which they were read

   message.writeString(eName);
   message.writeString(position);
   message.writeDouble(rate);

   //implement the logic necessary to deal with the message
   }

To stop the delivery of messages, whether Pub/Sub or P2P, the stop method is called.

TopicConnection.start( ); //pub-sub

QueueConnection.start( ); //P2P

Other J2EE components -- servlets or EJBs -- may act as message producers; however, they may only do so synchronously due to their request-response nature. No discussion of JMS would be complete without at least brief mention being made of the EJB 2.0 proposed final draft, which has introduced a new EJB, the Message Drive Bean -- the way to send XML-based messages. Although XML is not currently a supported message type, sending an XML document is as simple as creating a text message type and adding the XML document to the payload of the message, thereby sending data in a non-proprietary manner. It is worth noting, however, that some JMS vendors have an XML message type available. But using non-standard message types may risk portability.

String reportData; //the contents of reportData = XML document
TextMessage message;

message = session.createTextMessage();
message.setText (reportData);

A message driven bean (MDB) is an asynchronous message consumer invoked by the container when messages arrive. Unlike entity or session EJB, MDBs have no home or remote interfaces and are anonymous; they're aren't visible to clients. MDBs participate in a JMS-based system as a consumer, implementing business logic on the server. A client may locate a JMS destination associated with an MDB by using JNDI. For example,

Context initialContext = new InitialContext(); 
Queue reportInfoQueue = (javax.jms.Queue)initialContext.lookup 
                        (“java:comp/env/jms/reportInfoQueue”);

The MDB is composed of the Bean class and corresponding XML deployment descriptor. The Bean class implements the MessageDriveBean interface:

import javax.ejb.*; 
import jms.Message.*;


public interface MessageDriveBean {


  public void ejbCreate(); 
  public void ejbRemove(); 
  public void setMessageDrivenContext(MessageDrivenContext ctx); 
 }

And the MessageListener interface:

import javax.jms.*; 
         
public interface MessageListener { 
   
   public void onMessage( ); 
  } 

The Deployment Descriptor

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_2_0.dtd">
<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>MDB</ejb-name>
<ejb-class>MDB</ejb-class>
<transaction-type>Container</transaction-type>
<message-driven-destination>
<jms-destination-type>javax.jms.Queue</jms-destination-type>
</message-driven-destination>
<security-identity>
<run-as-specified-identity>
<role-name>everyone</role-name>
</run-as-specified-identity>
</security-identity>
</message-driven>
</enterprise-beans>
</ejb-jar>

Now that we have covered the basics of JMS that you will need to get started. What can you build with JMS? Just about anything.

For example, systems exist for sales, inventory, customer service, and accounting departments, respectively. These departmental systems have most likely been around for some time and the processing required to move transactions through to update all of these systems is no small task. This is where a message service would be appropriate.

A salesperson works to complete a sale and during the transaction inventory levels will be verified. When the salesperson completes the sales transaction, a message is be sent to the inventory system for fulfillment; once the order is filled a message is then sent to the shipping and receiving folks indicating the order is ready for shipment. When the order is successfully shipped that system would then notify the customer service and accounting systems that the order shipping successfully. All corresponding updates to each system take place automatically based on messages sent to each respective system.

JMS is not used to integrate just one organization, but, rather, JMS can integrate many organizations that may participate in message driven environments (think: supply chain partnerships). JMS is a significant tool in the development and integration of enterprise applications. Since many companies have a combination of legacy systems and newly developed systems, the use of messaging is a significant step toward integrating the entire enterprise, whether the systems are all contained within the same organization or multiple organizations.

TA Flores is an independent enteprise Java developer.


Return to ONJava.com.