The Java Message Service (JMS) is a specification that provides a consistent Java API for accessing message-oriented middleware services. This paper presents a test harness that automates the testing of JMS implementations (providers) for correctness and performance. Since the JMS specification is expressed in informal language, a formal model for JMS behavior is developed, based on the I/O automata used in other group communication systems. The test harness has been successfully used to test a number of JMS implementations. This paper contains a descriptive presentation of the formal model, the full details are found in a technical report
Messaging systems are used to build highly reliable, scalable, and flexible distributed applications.
Distributed applications are proliferating, as are a host of previously unexplored problems of synchronization, reliability, scalability, and security. One solution is a Messaging System built from loosely coupled components communicating through messages.
2.1. What is a Messaging System?
In its essence, a messaging system allows separate, uncoupled applications to reliably communicate asynchronously. The messaging system architecture generally replaces the client/server model with a peer-to-peer relationship between individual components, where each peer can send and receive messages to and from other peers.
Messaging systems provide a host of powerful advantages over other, more conventional distributed computing models. Primarily, they encourage "loose coupling" between message consumers and message producers.
This permits dynamic, reliable, and flexible systems to be built, whereby entire ensembles of sub-applications can be modified without affecting the rest of the system.
Other advantages of messaging systems include high scalability (commercial implementations boast the ability to support tens of thousands of clients and tens of thousands of operations per second), easy integration into heterogeneous networks, and reliability due to lack of a single point of failure.
Because of the reliable and scalable nature of messaging systems, they are used to solve many business and computing science problems. For example, they are the basis of such diverse applications as workflow, network management, communication services (voice over IP, voicemail, pager, email), customer care, weather forecasting, supply chain management, and many other systems. In addition, messaging systems are also invaluable as "glue" to bring together the disparate systems that inevitably result from mergers and acquisitions.
2.2. Messaging:
In general, messaging (also called electronic messaging) is the creation, storage, exchange, and management of text, images, voice, telex, fax, e-mail, paging, and Electronic Data Interchange (EDI) over a communications network.
In programming, messaging is the exchange of messages (specially-formatted data describing events, requests, and replies) to a messaging server, which acts as a message exchange program for client programs.
There are two major messaging server models: the point-to-point model and the publish/subscribe model. Messaging allows programs to share common message-handling code, to isolate resources and interdependencies, and to easily handle an increase in message volume. Messaging also makes it easier for programs to communicate across different programming environments (languages, compilers, and operating systems) since the only thing that each environment needs to understand is the common messaging format and protocol.
IBM's MQSeries and Sun Microsystems Java Message Service (JMS) are examples of products that provide messaging interfaces and services.
2.3. What is message passing?
Message passing is a general term for a variety of strategies for high-level, structured interclient communication. For example, a mobile agent framework could provide classes and methods with which two agents (on two different computers) send each other message. JMS supports the message passing strategies, i.e. point-to-point and publish/subscribe. JMS can be utilized by any (Java-based) distributed software components; of course, the JMS middleware must be available.
2.4. Enterprise messaging systems:
The Java Message Service was developed by Sun Microsystems to provide a means for
Java programs to access enterprise messaging systems.
Enterprise messaging systems, often known as message oriented middleware (MOM),
provide a mechanism for integrating applications in a loosely coupled, flexible manner. They provide asynchronous delivery of data between applications on a store and forward basis;
That is, the applications do not communicate directly with each other, but instead
communicate with the MOM, which acts as an intermediary.
The MOM provides assured delivery of messages (or at least makes its best effort) and
relieves application programmers from knowing the details of remote procedure calls (RPC) and networking/communications protocols.
2.5. Messaging flexibility:
Let, Application A communicates with Application B by sending a message through the MOM's application programming interface (API).
The MOM routes the message to Application B, which may exist on a completely different computer; the MOM handles the network communications. If the network connection is not available, the MOM will store the message until the connection becomes available, and then forward it to Application B.
Another aspect of flexibility is that Application B may not even be executing when Application A sends its message. The MOM will hold the message until Application B begins execution and attempts to retrieve its messages. This also prevents Application A from blocking while it waits for Application B to receive the message.
This asynchronous communication requires applications to be designed somewhat differently than most are designed today, but it can be an extremely useful method for
Time-independent or parallel processing.
2.6 Loose coupling:
The real power of enterprise messaging systems lies in the loose coupling.
In the previous example, Application A sends its messages indicating a particular destination, for example "order processing." Today, Application B provides order processing capabilities.
But, in the future, we can replace Application B with a different order-processing program, and Application A will be none the wiser. It will continue to send its messages to "order processing" and the messages will continue to be processed.
Likewise, we could replace Application A, and as long as the replacement continued to send messages for "order processing," the order-processing program would not need to know there is a new application sending orders.
3: JMS
3.1. JMS API:
The JMS API is provided in the Java package javax.jms.
3.2. What is API (Application Program Interface)?
An application program interface is the specific method prescribed by a computer operating system or by an application program by which a programmer writing an application program can make requests of the operating system or another application.
An API can be contrasted with a graphical user interface or a command interface (both of which are direct user interfaces) as interfaces to an operating system or a program.
3.3 Java Message Service (JMS):
Java Message Service, part of the J2EE (Java 2 Enterprise Edition) suite, provides standard APIs that Java developers can use to access the common features of enterprise message systems. The Java Message Service (JMS) API is an enterprise messaging tool for building enterprise applications. By combining Java technology with enterprise messaging, the JMS API provides a common provider framework that enables the development of portable, message based applications
Java Message Service (JMS) is a specification for message passing and related operations among distributed software components. JMS vendors implement the specification, providing the requisite API library, plus a broker, or server, that handles message passing among clients. Programmers then implement applications that communicate with each other by way of the vendor's JMS software.
Sun's JMS provides a common interface to standard messaging protocols and also to special messaging services in support of Java programs. Sun advocates the use of the Java Message Service for anyone developing Java applications, which can be run from any major operating system platform.
The messages involved exchange crucial data between computers - rather than between users - and contain information such as event notification and service requests. Messaging is often used to coordinate programs in dissimilar systems or written in different programming languages.
Using the JMS interface, a programmer can invoke the messaging services of IBM's MQSeries, Progress Software's SonicMQ, and other popular messaging product vendors. In addition, JMS supports messages that contain serialized Java objects and messages that contain Extensible Markup Language (XML) pages.
Message queuing systems form the front-line interface between businesses (B2B) and for Enterprise Application Integration (EAI). As such, message queuing systems are often called "middleware" because they operate in the middle -- between other systems and between enterprises.
Figur 3.3.1. Messaging Sevice.
The heck with hub-and-spoke designs: Enterprises are better off doing their integrating at the edges of their networks.
3.4. JMS objectives:
There are many enterprise messaging products on the market today, and several of the
companies that produce these products were involved in the development of JMS.
These existing systems vary in capability and functionality. The authors knew that JMS would be too complicated and unwieldy if it incorporated all of the features of all existing systems.
Likewise, they believed that they could not limit themselves to only the features that all of the systems had in common.
The authors believed that it was important that JMS include all of the functionality required to implement "sophisticated enterprise applications."
3.5 The objectives of JMS:
Define a common set of messaging concepts and facilities.
Minimize the concepts a programmer must learn to use enterprise messaging.
Maximize the portability of messaging applications.
Minimize the work needed to implement a provider.
Provide client interfaces for both point-to-point and pub/sub domains.
"Domains" is the JMS term for the messaging models
APPLICATIONS OF JMS
Simple Chat example
Book warehouse example
Stock trader application
Web Logic JMS application
We will develop the simple chat example in detail:
4.1. The Chat Application:
Internet chat provides an interesting application for learning about the JMS pub/sub-messaging model. Used mostly for entertainment, web-based chat applications can be found on thousands of web sites. In a chat application, people join virtual chat rooms where they can "chat" with a group of other people.
To illustrate how JMS works, we will use the JMS pub/sub API to build a simple chat application. The requirements of Internet chat map neatly onto the publish-and-subscribe messaging model. In this model, a producer can send a message to many consumers by delivering the message to a single topic. A message producer is also called a publisher and a message consumer is also called a subscriber. The following source code is a JMS-based chat client. Every participant in a chat session uses this Chat program to join a specific chat room (topic), and deliver and receive messages to and from that room: package chap2.chat;import javax.jms.*;import javax.naming.*;import java.io.*;import java.io.InputStreamReader;import java.util.Properties; public class Chat implements javax.jms.MessageListener{ private TopicSession pubSession; private TopicSession subSession; private TopicPublisher publisher; private TopicConnection connection; private String username; /* Constructor. Establish JMS publisher and subscriber */ public Chat(String topicName, String username, String password) throws Exception { // Obtain a JNDI connection Properties env = new Properties( ); // ... specify the JNDI properties specific to the vendor InitialContext jndi = new InitialContext(env); // Look up a JMS connection factory TopicConnectionFactory conFactory = (TopicConnectionFactory)jndi.lookup("TopicConnectionFactory"); // Create a JMS connection TopicConnection connection = conFactory.createTopicConnection(username,password); // Create two JMS session objects TopicSession pubSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); TopicSession subSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); // Look up a JMS topic Topic chatTopic = (Topic)jndi.lookup(topicName); // Create a JMS publisher and subscriber TopicPublisher publisher = pubSession.createPublisher(chatTopic); TopicSubscriber subscriber = subSession.createSubscriber(chatTopic); // Set a JMS message listener subscriber.setMessageListener(this); // Intialize the Chat application set(connection, pubSession, subSession, publisher, username); // Start the JMS connection; allows messages to be delivered connection.start( ); } /* Initialize the instance variables */ public void set(TopicConnection con, TopicSession pubSess, TopicSession subSess, TopicPublisher pub, String username) { this.connection = con; this.pubSession = pubSess; this.subSession = subSess; this.publisher = pub; this.username = username; } /* Receive message from topic subscriber */ public void onMessage(Message message) { try { TextMessage textMessage = (TextMessage) message; String text = textMessage.getText( ); System.out.println(text); } catch (JMSException jmse){ jmse.printStackTrace( ); } } /* Create and send message using topic publisher */ protected void writeMessage(String text) throws JMSException { TextMessage message = pubSession.createTextMessage( ); message.setText(username+" : "+text); publisher.publish(message); } /* Close the JMS connection */ public void close( ) throws JMSException { connection.close( ); } /* Run the Chat client */ public static void main(String [] args){ try{ if (args.length!=3) System.out.println("Topic or username missing"); // args[0]=topicName; args[1]=username; args[2]=password Chat chat = new Chat(args[0],args[1],args[2]); // Read from command line BufferedReader commandLine = new java.io.BufferedReader(new InputStreamReader(System.in)); // Loop until the word "exit" is typed while(true){ String s = commandLine.readLine( ); if (s.equalsIgnoreCase("exit")){ chat.close( ); // close down connection System.exit(0);// exit program } else chat.writeMessage(s); } } catch (Exception e){ e.printStackTrace( ); } }}
4.2. Getting Started with the Chat Example:
To put this client to use, we have to compile it like any other Java program. Then start our JMS server, setting up topics, usernames, and passwords, as we want. Configuration of a JMS server is vendor-dependent.
The Chat class includes a main() method so that it can be run as a standalone Java application. It's executed from the command line as follows:java chap2.chat.Chat topic username password
The topic is the destination that we want to publish-and-subscribe to; username and password make up the authentication information for the client. We have to Run at least two chat clients in separate command windows and try typing into one; we should see the text type displayed by the other client.
The chat client creates a JMS publisher and subscriber for a specific topic. The topic represents the chat room. The JMS server registers all the JMS clients that want to publish or subscribe to a specific topic. When text is entered at the command line of one of the chat clients, it is published to the messaging server. The messaging server identifies the topic associated with the publisher and delivers the message to all the JMS clients that have subscribed to that topic.
Figure 4.2.1. The chat client
4.3. Bootstrapping the JMS client:
The main() method bootstraps the chat client and provides a command-line interface. Once an instance of the Chat class is created, the main() method spends the rest of its time reading text typed at the command line and passing it to the Chat instance using the instance's writeMessage() method.
The Chat instance connects to the topic and receives and delivers messages. The Chat instance starts its life in the constructor, which does all the work to connect to the topic and set up the TopicPublisher and TopicSubscribers for delivering and receiving messages.
4.4. Obtaining a JNDI connection:
The chat client starts by obtaining a JNDI connection to the JMS messaging server. JNDI is an implementation-independent API for directory and naming systems. A directory service provides JMS clients with access to ConnectionFactory and Destinations (topics and queues) objects. ConnectionFactory and Destination objects are the only things in JMS that cannot be obtained using the JMS API--unlike connections, sessions, producers, consumers, and messages, which are manufactured using the JMS API. JNDI provides a convenient, location-transparent, configurable, and portable mechanism for obtaining ConnectionFactory and Destination objects, also called JMS administered objects because they are established and configured by a system administrator.
Using JNDI, a JMS client can obtain access to a JMS provider by first looking up a ConnectionFactory. The ConnectionFactory is used to create JMS connections, which can then be used for sending and receiving messages. Destination objects, which represent virtual channels (topics and queues) in JMS, are also obtained via JNDI and are used by the JMS client. The directory service can be configured by the system administrator to provide JMS administered objects so that the JMS clients don't need to use proprietary code to access a JMS provider.
JMS servers will either work with a separate directory service (e.g., LDAP) or provide their own directory service that supports the JNDI API. The constructor of the Chat class starts by obtaining a connection to the JNDI naming service used by the JMS server:
4.5. Understanding JNDI:
JNDI is a standard Java extension that provides a uniform API for accessing a variety of directory and naming services. In this respect, it is somewhat similar to JDBC. JDBC lets you write code that can access different relational databases such as Oracle, SQLServer, or Sybase; JNDI lets you write code that can access different directory and naming services, such as LDAP, Novell Netware NDS, CORBA Naming Service, and proprietary naming services provided by JMS servers.
In JMS, JNDI is used mostly as a naming service to locate administered objects. Administered objects are JMS objects that are created and configured by the system administrator. Administered objects include JMS ConnectionFactory and Destination objects like topics and queues.
Administered objects are bound to a name in a naming service. An example of a naming service is the DNS, which converts an Internet hostname like www.oreilly.com into a network address that browsers use to connect to web servers. There are many other naming services, such as COSNaming in CORBA and the Java RMI registry. Naming services allow printers, distributed objects, and JMS administered objects to be bound to names and organized in a hierarchy similar to a filesystem. A directory service is a more sophisticated kind of naming service.
JNDI provides an abstraction that hides the specifics of the naming service, making client applications more portable. Using JNDI, JMS clients can browse a naming service and obtain references to administered objects without knowing the details of the naming service or how it is implemented. JMS servers are usually be used in combination with a standard JNDI driver (a.k.a. service provider) and directory service like LDAP, or provide a proprietary JNDI service provider and directory service.
JNDI is both virtual and dynamic. It is virtual because it allows one naming service to be linked to another. Using JNDI, we can drill down through directories to files, printers, JMS administered objects, and other resources following virtual links between naming services. The user doesn't know or care where the directories are actually located. As an administrator, you can create virtual directories that span a variety of different services over many different physical locations.
JNDI is dynamic because it allows the JNDI drivers for specific types of naming and directory services to be loaded dynamically at runtime. A driver maps a specific kind of naming or directory service into the standard JNDI class interfaces. // Obtain a JNDI connectionProperties env = new Properties( );// ... specify the JNDI properties specific to the vendor InitialContext undid = new InitialContext(env);
Creating a connection to a JNDI naming service requires that a javax.naming.InitialContext object be created. An InitialContext is the starting point for any JNDI lookup--it's similar in concept to the root of a filesystem. The InitialContext provides a network connection to the directory service that acts as a root for accessing JMS administered objects. The properties used to create an InitialContext depend on which JMS directory service you are using. The code used to create a JNDI InitialContext in BEA's Weblogic naming service, for example, would look something like this: Properties env = new Properties( );env.put(Context.SECURITY_PRINCIPAL, "guest"); env.put(Context.SECURITY_CREDENTIALS, "guest");env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");env.put(Context.PROVIDER_URL, "t3://localhost:7001"); InitialContext jndi = new InitialContext(env);
When SonicMQ is used in combination with a third party LDAP directory service, the connection properties would be very different. For example, the following shows how a SonicMQ JMS client would use JNDI to access JMS administered objects stored in a LDAP directory server:Properties env = new Properties( );env.put(Context.SECURITY_PRINCIPAL, "guest"); env.put(Context.SECURITY_CREDENTIALS, "guest");env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=acme.com"); InitialContext jndi = new InitialContext(env);
The TopicConnectionFactory:
Once a JNDI InitialContext object is instantiated, it can be used to look up the TopicConnectionFactory in the messaging server's naming service: TopicConnectionFactory conFactory = (TopicConnectionFactory)jndi.lookup("TopicConnectionFactory");
The javax.jms.TopicConnectionFactory is used to manufacture connections to a message server. A TopicConnectionFactory is a type of administered object, which means that its attributes and behavior are configured by the system administrator responsible for the messaging server. The TopicConnectionFactory is implemented differently by each vendor. Connection factory might, for example, be configured to manufacture connections that use a particular protocol, security scheme, clustering strategy, etc. A system administrator might choose to deploy several different TopicConnectionFactory objects, each configured with its own JNDI lookup name.
The TopicConnectionFactory provides two overloaded versions of the createTopicConnection( ) method: package javax.jms; public interface TopicConnectionFactory extends ConnectionFactory { public TopicConnection createTopicConnection( ) throws JMSException, JMSSecurityException; public TopicConnection createTopicConnection(String username, String password) throws JMSException, JMSSecurityException;}
These methods are used to create TopicConnection objects. The behavior of the no-arg method depends on the JMS provider. Some JMS providers will assume that the JMS client is connecting under anonymous security context, while other providers may assume that the credentials can be obtained from JNDI or the current thread. The second method provides the client with a username-password authentication credential, which can be used to authenticate the connection. In our code, we choose to authenticate the connection explicitly with a username and password.
4.6. The TopicConnection:
The TopicConnection is created by the TopicConnectionFactory : // Look up a JMS connection factoryTopicConnectionFactory conFactory = (TopicConnectionFactory)jndi.lookup("TopicConnectionFactory"); // Create a JMS connection TopicConnection connection = conFactory.createTopicConnection(username, password);
The TopicConnection represents a connection to the message server. Each TopicConnection that is created from a TopicConnectionFactory is a unique connection to the server. JMS client might choose to create multiple connections from the same connection factory, but this is rare as connections are relatively expensive (each connection requires a network socket, I/O streams, memory, etc.). Creating multiple Session objects (discussed later in this chapter) from the same connection is considered more efficient, because sessions share access to the same connection. The TopicConnection is an interface that extends javax.jms.Connection interface. It defines several general-purpose methods used by clients of the TopicConnection. Among these methods are the start( ), stop( ), and close( ) methods: // javax.jms.Connection the super interfacepublic interface Connection { public void start() throws JMSException; public void stop() throws JMSException; public void close() throws JMSException; ...} // javax.jms.TopicConnection extends javax.jms.Connectionpublic interface TopicConnection extends Connection { public TopicSession createTopicSession(boolean transacted, int acknowledgeMode) throws JMSException; ...}
The start(), stop(), and close() methods allow a client to manage the connection directly. The start() method turns the inbound flow of messages "on," allowing messages to be received by the client. This method is used at the end of the constructor in Chat class: ... // Intialize the Chat application set(connection, pubSession, subSession, publisher, username); connection.start( ); }
It is a good idea to start the connection after the subscribers have been set up, because the messages start to flow in from the topic as soon as start() is invoked.
The stop( ) method blocks the flow of inbound messages until the start( ) method is invoked again. The close( ) method is used to close the TopicConnection to the message server. This should be done when a client is finished using the TopicConnection; closing the connection conserves resources on the client and server. In the Chat class, the main( ) method calls Chat.close( ) when "exit" is typed at the command line. The Chat.close( ) method in turn calls the TopicConnection.close( ) method: public void close( ) throws JMSException { connection.close( );}
Closing a TopicConnection closes all the objects associated with the connection including the TopicSession, TopicPublisher, and TopicSubscriber.
4.7. The TopicSession:
After the TopicConnection is obtained, it's used to create TopicSession objects: // Create a JMS connectionTopicConnection connection =conFactory.createTopicConnection(username,password); // Create two JMS session objectsTopicSession pubSession =connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);TopicSession subSession =connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
A TopicSession object is a factory for creating Message, TopicPublisher, and TopicSubscriber objects. A client can create multiple TopicSession objects to provide more granular control over publishers, subscribers, and their associated transactions. In this case we create two TopicSession objects, pubSession and subSession.
The boolean parameter in the createTopicSession( ) method indicates whether the Session object will be transacted. A transacted Session automatically manages outgoing and incoming messages within a transaction. The second parameter indicates the acknowledgment mode used by the JMS client. An acknowledgment is a notification to the message server that the client has received the message. In this case we chose AUTO_ACKNOWLEDGE, which means that the message is automatically acknowledged after it is received by the client.
The TopicSession objects are used to create the TopicPublisher and TopicSubscriber. The TopicPublisher and TopicSubscriber objects are created with a Topic identifier and are dedicated to the TopicSession that created them; they operate under the control of a specific TopicSession: TopicPublisher publisher = pubSession.createPublisher(chatTopic);TopicSubscriber subscriber = subSession.createSubscriber(chatTopic);
The TopicSession is also used to create the Message objects that are delivered to the topic. The pubSession is used to create Message objects in the writeMessage( ) method. When you type text at the command line, the main( ) method reads the text and passes it to the Chat instance by invoking writeMessage( ). The writeMessage( ) method (shown in the following example) uses the pubSession object to generate a TextMessage object that can be used to deliver the text to the topic: protected void writeMessage(String text) throws JMSException{ TextMessage message = pubSession.createTextMessage( ); message.setText(username+" : "+text); publisher.publish(message);}
Several Message types can be created by a TopicSession. The most commonly used type is the TextMessage.
4.8. The Topic:
JNDI is used to locate a Topic object, which is an administered object like the TopicConnectionFactory : InitialContext jndi = new InitialContext(env);..// Look up a JMS topicTopic chatTopic = (Topic)jndi.lookup(topicName);
A Topic object is a handle or identifier for an actual topic, called a physical topic, on the messaging server. A physical topic is an electronic channel to which many clients can subscribe and publish. A topic is analogous to a news group or list server: when a message is sent to a news group or list server, it is delivered to all the subscribers. Similarly, when a JMS client delivers a Message object to a topic, all the clients subscribed to that topic receive the Message.
The Topic object encapsulates a vendor-specific name for identifying a physical topic in the messaging server. The Topic object has one method, getName( ), which returns the name identifier for the physical topic it represents. The name encapsulated by a Topic object is vendor-specific and varies from product to product. For example, one vendor might use dot (".") separated topic names, like "oreilly.jms.chat", while another vendor might use a completely different naming system, similar to LDAP naming, "o=oreilly,cn=chat". Using topic names directly will result in client applications that are not portable across brands of JMS servers. The Topic object hides the topic name from the client, making the client more portable.
As a convention, we'll refer to a physical topic as a topic and only use the term "physical topic" when it's important to stress its difference from a Topic object.
4.9. The TopicPublisher:
A TopicPublisher was created using the pubSession and the chatTopic: // Look up a JMS topicTopic chatTopic = (Topic)jndi.lookup(topicName); // Create a JMS publisher and subscriber TopicPublisher publisher = pubSession.createPublisher(chatTopic);
A TopicPublisher is used to deliver messages to a specific topic on a message server. The Topic object used in the createPublisher( ) method identifies the topic that will receive messages from the TopicPublisher. In the Chat example, any text typed on the command line is passed to the Chat class's writeMessage( ) method. This method uses the TopicPublisher to deliver a message to the topic: protected void writeMessage(String text) throws JMSException{ TextMessage message = pubSession.createTextMessage( ); message.setText(username+" : "+text); publisher.publish(message);}
The TopicPublisher objects deliver messages to the topic asynchronously. Asynchronous delivery and consumption of messages is a key characteristic of Message-Oriented Middleware; the TopicPublisher doesn't block or wait until all the subscribers receive the message. Instead, it returns from the publish( ) method as soon as the message server receives the message. It's up to the message server to deliver the message to all the subscribers for that topic.
4.10. The TopicSubscriber:
The TopicSubscriber is created using the subSession and the chatTopic: // Look up a JMS topicTopic chatTopic = (Topic)jndi.lookup(topicName); // Create a JMS publisher and subscriber TopicPublisher publisher = pubSession.createPublisher(chatTopic);TopicSubscriber subscriber = subSession.createSubscriber(chatTopic);
A TopicSubscriber receives messages from a specific topic. The Topic object argument used in the createSubscriber( ) method identifies the topic from which the TopicSubscriber will receive messages.
The TopicSubscriber receives messages from the message server one at a time (serially). These messages are pushed from the message server to the TopicSubscriber asynchronously, which means that the TopicSubscriber does not have to poll the message server for messages. In our example, each chat client will receive any message published by any of the other chat clients. When a user enters text at the command line, the text message is delivered to all other chat clients that subscribe to the same topic.
The pub/sub messaging model in JMS includes an in-process Java event model for handling incoming messages. This is similar to the event-driven model used by Java beans.An object simply implements the listener interface, in this case the MessageListener, and then is registered with the TopicSubscriber. A TopicSubscriber may have only one MessageListener object. Here is the definition of the MessageListener interface used in JMS: package javax.jms; public interface MessageListener { public void onMessage(Message message);}
When the TopicSubscriber receives a message from its topic, it invokes the onMessage() method of its MessageListener objects. The Chat class itself implements the MessageListener interface and implements the onMessage() method: public class Chat implements javax.jms.MessageListener{ public void onMessage(Message message){ try{ TextMessage textMessage = (TextMessage)message; String text = textMessage.getText( ); System.out.println(text); } catch (JMSException jmse){jmse.printStackTrace( );} } ...}
The Chat class is a MessageListener type, and therefore registers itself with the TopicSubscriber in its constructor: TopicSubscriber subscriber = subSession.createSubscriber(chatTopic); subscriber.setMessageListener(this);
When the message server pushes a message to the TopicSubscriber, the TopicSubscriber invokes the Chat object's onMessage( ) method.
It's fairly easy to confuse the Java Message Service with its use of a Java event model. JMS is an API for asynchronous distributed enterprise messaging that spans processes and machines across a network. The Java event model is used to synchronously deliver events by invoking methods on one or more objects in the same process that have registered as listeners. The JMS pub/sub model uses the Java event model so that a TopicSubscriber can notify its MessageListener object in the same process that a message has arrived from the message server.
4.11. The Message:
In the chat example, the TextMessage class is used to encapsulate the messages we send and receive. A TextMessage contains a java.lang.String as its body and is the most commonly used message type. The onMessage( ) method receives TextMessage objects from the TopicSubscriber. Likewise, the writeMessage() method creates and publishes TextMessage objects using the TopicPublisher:public void onMessage(Message message){ try{ TextMessage textMessage = (TextMessage)message; String text = textMessage.getText( ); System.out.println(text); } catch (JMSException jmse){jmse.printStackTrace( );}}protected void writeMessage(String text) throws JMSException{ TextMessage message = pubSession.createTextMessage( ); message.setText(username+" : "+text); publisher.publish(message);}
A message basically has two parts: a header and payload. The header is comprised of special fields that are used to identify the message, declare attributes of the message, and provide information for routing. The difference between message types is determined largely by their payload, i.e., the type of application data the message contains. The Message class, which is the superclass of all message objects, has no payload. It is a lightweight message that delivers no payload but can serve as a simple event notification. The other message types have special payloads that determine their type and use:
Message:
This type has no payload. It is useful for simple event notification.
TextMessage:
This type carries a java.lang.String as its payload. It is useful for exchanging simple text messages and also for more complex character data, such as XML documents.
ObjectMessage:
This type carries a serializable Java object as its payload. It's useful for exchanging Java objects.
BytesMessage:
This type carries an array of primitive bytes as its payload. It's useful for exchanging data in an application's native format, which may not be compatible with other existing Message types. It is also useful where JMS is used purely as a transport between two systems, and the message payload is opaque to the JMS client.
Stream Message:
This type carries a stream of primitive Java types (int, double, char, etc.) as its payload. It provides a set of convenience methods for mapping a formatted stream of bytes to Java primitives. It's an easy programming model when exchanging primitive application data in a fixed order.
Map Message:
This type carries a set of name-value pairs as its payload. The payload is similar to a java.util.Properties object, except the values must be Java primitives their wrappers. The Map Message is useful for delivering keyed data.
4.12. Sessions and Threading:
The Chat application uses a separate session for the publisher and subscriber, pubSession and subSession, respectively. This is due to a threading restriction imposed by JMS. According to the JMS specification, a session may not be operated on by more than one thread at a time. In our example, two threads of control are active: the default main thread of the Chat application and the thread that invokes the onMessage( ) handler. The thread that invokes the onMessage( ) handler is owned by the JMS provider. Since the invocation of the onMessage( ) handler is asynchronous, it could be called while the main thread is publishing a message in the writeMessage( ) method. If both the publisher and subscriber had been created by the same session, the two threads could operate on these methods at the same time; in effect, they could operate on the same TopicSession concurrently--a condition that is prohibited.
A goal of the JMS specification was to avoid imposing an internal architecture on the JMS provider. Requiring a JMS provider's implementation of a Session object to be capable of safely handling multiple threads was specifically avoided. This is mostly due to one of the intended uses of JMS--that the JMS API be a wrapper around an existing messaging system, which may not have multithreaded delivery capabilities on the client.
The requirement imposed on the JMS provider is that the sending of messages and the asynchronous receiving of messages be processed serially. It is possible to publish-and-subscribe using the same session, but only if the application is publishing from within the onMessage( ) handler.
Finally we can summarize it in the following details:
1. Thread-specific storage is used with the Java Authentication and Authorization Service (JAAS) to allow security credentials to transparently propagate between resources and applications.
2. The actual physical network connection may or may not be unique depending on the vendor. However, the connection is considered to be logically unique so authentication and connection control can be managed separately from other connections.
3. Although the in-process event model used by TopicSubscriber is similar to the one used in Java beans, JMS itself is an API and the interfaces it defines are not Java beans.
5: JMS COMPONENT & ELEMENT
5.1. JMS elements:
JMS consists of several elements:
JMS provider:
An implementation of the JMS interface for a Message Oriented Middleware (MOM). Providers are implemented as either a Java JMS implementation or an adapter to a non-Java MOM.
JMS client:
A Java-based application or object that produces and/or consumes messages.
JMS producer:
A JMS client that creates and sends messages.
JMS consumer:
A JMS client that receives messages.
JMS message:
An object that contains the data being transferred between JMS clients.
JMS queue:
A staging area that contains messages that have been sent and are waiting to be read. As the name queue suggests, the messages are delivered in the order sent. A message is removed from the queue once it has been read.
JMS topic
A distribution mechanism for publishing messages that are delivered to multiple subscribers.
5.2. JMS models:
The JMS API supports two models:
point-to-point or queuing model
publish and subscribe model
In the point-to-point or queuing model, a producer posts messages to a particular queue and a consumer reads messages from the queue. Here, the producer knows the destination of the message and posts the message directly to the consumer's queue. It is characterized by following:
Only one consumer will get the message
The producer does not have to be running at the time the receiver consumes the message, nor does the receiver need to be running at the time the message is sent
Every message successfully processed is acknowledged by the receiver
The publish/subscribe model supports publishing messages to a particular message topic. Zero or more subscribers may register interest in receiving messages on a particular message topic. In this model, neither the publisher nor the subscriber know about each other. A good metaphor for it is anonymous bulletin board. The following are characteristics of this model:
Multiple consumers can get the message
There is a timing dependency between publishers and subscribers. Publisher has to create a subscription in order for clients to be able to subscribe. Subscriber has to remain continuously active to receive messages, unless it has established a durable subscription. In that case, messages published while the subscriber is not connected will be redistributed whenever it will reconnect.
Using Java, JMS provides a way of separating the application from the transport layer of providing data. The same Java classes can be used to communicate with different JMS providers by using the JNDI information for the desired provider. The classes first use a connection factory to connect to the queue or topic, and then use populate and send or publish the messages. On the receiving side, the clients then receive or subscribe to the messages.
Messaging systems are classified into different models that determine which client receives a message. The most common messaging models are:
· Publish-Subscribe Messaging
· Point-To-Point Messaging
· Request-Reply Messaging Not all MOM providers support all these models.
5.3. Publish-Subscribe Messaging:
When multiple applications need to receive the same messages, Publish-Subscribe Messaging is used. The central concept in a Publish-Subscribe messaging system is the Topic. Multiple Publishers may send messages to a Topic, and all Subscribers to that Topic receive all the messages sent to that Topic. This model, as shown in Figure, is extremely useful when a group of applications want to notify each other of a particular occurrence.
The point to note in Publish-Subscribe Messaging is that, there may be multiple Senders and multiple Receivers.
Figure 5.3.1. Publish-Subscribe Based Messaging System
5.4. Point-To-Point Messaging:
When one process needs to send a message to another process, Point-To-Point Messaging can be used. However, this may or may not be a one-way relationship. The client to a Messaging system may only send messages, only receive messages, or send and receive messages. At the same time, another client can also send and/or receive messages. In the simplest case, one client is the Sender of the message and the other client is the Receiver of the message.There are two basic types of Point-to-Point Messaging systems.
The first one involves a client that directly sends a message to another client. The second and more common implementation is based on the concept of a Message Queue. Such a system is shown in Figure .
Figure 5.4.1.Queue Based (Point-to-Point) Messaging System
5.5. Request-ReplyMessaging:
When an application sends a message and expects to receive a message in return, Request-Reply Messaging can be used. This is the standard synchronous object-messaging format. This messaging model is often defined as a subset of one of the other two models. JMS does not explicitly support Request-Reply Messaging, though it allows it in the context of the other methods.
5.6. Basic point-to-point data link:
A traditional point-to-point data link is a communications medium with exactly two endpoints and no data or packet formatting. The host computers at either end had to take full responsibility for formatting the data transmitted between them. The connection between the computer and the communications medium was generally implemented through an RS-232 interface, or something similar. Computers in close proximity may be connected by wires directly between their interface cards.
When connected at a distance, each endpoint would be fitted with a modem to convert analog telecommunications signals into a digital data stream. When the connection used a telecommunications provider, the connections were called a dedicated, leased, or private line. The ARPANET used leased lines to provide point-to-point data links between its packet-switching nodes, which were called Interface Message Processors.
5.7. What is point-to-point messaging?
With point-to-point message passing the sending application/client establishes a named message queue in the JMS broker/server and sends messages to this queue. The receiving client registers with the broker to receive messages posted to this queue. There is a one-to-one relationship between the sending and receiving clients.
5.8. What is publish/subscribe messaging?
With publish/subscribe message passing the sending application/client establishes a named topic in the JMS broker/server and publishes messages to this queue. The receiving clients register (specifically, subscribe) via the broker to messages by topic; every subscriber to a topic receives each message published to that topic. There is a one-to-many relationship between the publishing client and the subscribing clients.
5.9. Java Message Service (JMS) Architecture:
Figure shows the JMS Architecture. As shown in Figure, JMS Service Providers implement the JMS interface on top of their messaging services. JMS defines Queues and Topics, but it does not require the provider to implement both. JMS thus tries to maximize portability of the solution with as many features possible.
Figure 5.9.1. The Java Message Service Architecture
5.10. The primary features of JMS are as follows:
Connection Factories are used in JMS to create connections to a specific JMS provider.In JMS, both Publish-Subscribe Messaging and Point-To-Point are implemented and defined by separate interfaces so that a Provider does not have to support both.JMS defines the concept of a Topic or a Queue as the target for a Message. Topics are used for Publish-Subscribe Messaging. Queues are used for Point-to-Point Messaging. The Providers’ code is defined by interfaces in JMS, freeing the implementation from the limitations of subclassing.JMS provides support for distributed transactions.The Java Message Service APIBoth Publish-Subscribe Messaging and Point-To-Point Messaging inherit from a common set of abstract interfaces as shown in Table 1.
JMS Parent
Publish-Subscribe Domain
Point-To-Point Domain
Destination
Topic
Queue
ConnectionFactory
TopicConnectionFactory
QueueConnectionFactory
Connection
TopicConnection
QueueConnection
Session
TopicSession
QueueSession
MessageProducer
TopicPublisher
QueueSender
MessageConsumer
TopicSubscriber
QueueReceiver, QueueBrowser
Table 5.10.1. Relationship of Point-To-Point and Publish-Subscribe interfaces
6: JAVA MESAGING ENSURES DATA DELIVERY
6.1. When it absolutely, positively has to get there, a jms server may be the answer:
Here the transmission of business data is concerned, just keeping fingers crossed and hoping for the best isn't good enough. If a company has gone to the trouble of linking its distributed systems so those systems can communicate, it's a safe bet that the data actually has to get where it was meant to go. Unfortunately, communications can and do break down, and while communication failure should never jeopardize data integrity in a well-designed system, repeated rollbacks take their toll in time, system load, and user patience.
When application developers can't afford "maybe" for an answer, one technology they turn to is messaging, usually in the form of message-oriented middleware. Messaging is relatively easy to implement and gives developers a straightforward guarantee that data transmitted between two processes was in fact sent and received, and in the order in which the messages were intended.
The idea behind messaging is simple: Between two or more distributed programs that need to communicate, you install an intermediary to which these processes send data in the form of discrete, one-way packages of information. Rather than letting the processes communicate directly, the intermediary stores these information packages--messages--and forwards them to the proper destination at the proper time. The intermediary, the message broker, is responsible for ensuring that the messages are indeed sent and received.
This is called asynchronous communication, because while the processes are communicating, they aren't doing it in real time. Contrast asynchronous messaging with other distributed programming models, such as Microsoft's Distributed Component Object Model, Corba, Java Remote Method Invocation, or remote procedure calls. These models let one process simultaneously and directly send and receive data to and from another process.
One of asynchronous messaging's main advantages is that in the event of application, system, or network failure, communication between applications is not compromised, it's simply postponed. The message broker will try to send the message until it receives confirmation from the destination process that the message has arrived.
This is especially important in today's networked world, where notebook PCs or handheld devices frequently go offline or the network itself becomes unavailable. Compare this with old standby remote procedure calls, where communication fails completely if one of the services becomes unavailable.
"The gorgeous thing about messaging is that it is so fundamentally simple," says George Kassabgi, VP of marketing and sales for Progress Software Corp. "I believe it is possible to successfully explain messaging to a 12-year-old."
Developers involved in application integration have been quick to latch onto the simplicity of messaging. Venerable message-oriented middleware products such as IBM's MQSeries have long been a staple of enterprise application integration projects.
Until recently, however, Java developers have not had a portable application programming interface for message-based communications, nor have independent software vendors had a standard Java messaging specification to work to. Fortunately for them, Sun Microsystems in mid-1998 rolled out the Java Message Service to fulfill those needs. The company is including JMS in its Java 2, Enterprise Edition, platform
Increasingly, developers are favoring products based on the JMS API in lieu of more tried-and-true messaging fare. JMS has inspired a number of messaging products, including SonicMQ from Progress Software, FioranoMQ by Fiorano Software, and Sun's Java Message Queue, set to be released by year's end.
Java application server vendors are also building JMS compatibility into their products as part of their efforts to attain Java 2, Enterprise Edition, compliance. These vendors include BEA Systems Inc. and Bluestone Software Inc.
6.2. What JMS cannot provide?
The following features, common in MOM products, are not addressed by the JMS
specification. While acknowledged by the JMS authors as important for the development of robust messaging applications, these features are considered JMS provider-specific.
JMS providers are free to implement these features in any manner they please, if at all:
Load balancing and fault tolerance
Error and advisory system messages and notification
Administration
Security
Wire protocol
Message type repository
Load Balancing/Fault Tolerance –
Many products provide support for multiple, cooperating clients implementing a critical service. The JMS API does not specify how such clients cooperate to appear to be a single, unifiedservice.
Error/Advisory Notification –
Most messaging products define system messages that provide asynchronous notification of problems or system events to clients. JMS does not attempt to standardize these messages. By following the guidelines defined by JMS, clients can avoid using these messages and thus prevent the portability problems their use introduces.
Administration –
JMS does not define an API for administering messagingproducts.
Security –
JMS does not specify an API for controlling the privacy and integrity of messages. It also does not specify how digital signatures or keys
are distributed to clients. Security is considered to be a JMS provider specific feature that is configured by an administrator rather than controlled via the JMS API by clients.
7: SOME ISSUES REGARDING JMS
1) Are there other messaging frameworks that use Java technology?
Yes. Prior to JMS, Java software for various distributed computing environments, for example, the WebLogic server, the Aglet framework for mobile agents, SoftWired's iBus software, and many others have provided a variety of message-oriented, interclient communication solutions for enterprise computing. In many cases, the messaging functionality is part of a larger distributed computing framework.
2) Does JMS support distributed transactions?
Distributed transaction services are provided via the Java Transaction API (JTA). JMS does not mandate JTA support. See the JMS vendor's documentation for JTA-related discussion, especially, whether or not the vendor supports JTA.
3) Does JMS provide load balancing, fault tolerance, scalability, and so on?
The JMS specification does not address these issues; hence, vendors are free to implement their own support, and many vendors do provide these services.
4) How does JMS compare to peer-to-peer distributed computing?
The term peer-to-peer is used in a variety of ways in distributed and network computing. One usage, at the application level, is to describe a distributed application scenario in with each distributed component potentially interacts with every other distributed component and maintains a network reference (access) to each component (using any of several mechanisms to do so, for example, via Enterprise JavaBeans and EJB servers resident on each network host, via simple RMI-based communication among applications, and so on).
With JMS, distributed components interact with the JMS broker via destinations (topics and queues), which then disseminates messages to the registered clients; thus, distributed components do not have to know (and manage) each others' network locations. As for the JMS middleware, it can use (behind the scenes) any of several network topologies, for example, bus, ring, hierarchical, fully connected (peer-to-peer), star (hub-and-spoke), or others, including hybrids.
Messaging systems are peer-to-peer distributed systems in the sense that, at least potentially, every (registered) client can communicate with every other (registered) client.
5) Is it possible for a client to send multiple messages and ensure that the entire set of messages is delivered?
The preferred method for handling interdependent messages is to produce them within a transacted session. See Session.commit(), Session.rollback(), and XASession.
Is it possible for server-side applications, for example, a JMS application, to play the role of a resource in a distributed transaction?
Under certain conditions, yes. In this particular case, the JMS server would have to implement the appropriate resource-related interfaces in javax.transaction.xa so that the JTS transaction manager can enlist the JMS server as an intermediary, playing the role of a resource manager with respect to the JMS application.
6) Is it possible to use transacted sessions with other Java-technology, transaction-processing facilities, for example, JTA?
No. It is possible (if provided by the JMS implementation) to use JTA in the context of a session, but not a transacted session. That is, you cannot use Session.commit() and Session.rollback() in a context that's controlled by an instance of UserTransaction.
If, for example, one or more messages, in conjunction with database operations, all form a "logical transactional unit," it's usually best to take advantage of the transaction support provided by the JDBC driver, possibly augmenting this transacted (database) server operation with, javax.transaction.UserTransaction from the Java Transaction API (JTA), if JTA is implemented by the JMS server. Note that JMS implementations vary in their support for distributed transaction processing. See the javax.jms.XA... interfaces in the API documentation.
7) What else is missing from JMS?
The answer depends on your point of view. From one point of view, nothing is missing. In terms of common distributed computing-related functionality, typically present in larger Java application servers, JMS does not mandate functionality related to the following:
Administration
Error, or system event, notification
Load balancing, scalability
Low-level transport protocol
Security
8) What is the role of the JMS server? Why is it necessary?
The server, message broker, or whatever it is called, functions as an intermediary. Suppose a distributed component wants to send (financial) stock information to one or more remotely located distributed components. Rather than having to know the exact clients to which it sends messages containing stock information, it can establish either a message queue or a message topic area (depending on the message-passing scheme, point-to-point or publish/subscribe) with the JMS server and "post" the stock information with the server, which then distributes the messages to the appropriately registered receiving clients.
Also, without this intermediary, the sending client would have the burden of monitoring whether or not the receiving client is currently connected, whether or not a network failure occurred during the send operation, and so on. The server plays an important role in transparently handling many network-related issues, including reliable message delivery, which can require transaction processing and/or persistent message storage.
9) What software do I need in order to add JMS message passing to my enterprise exists distributed applications?
The "J" in JMS stands for Java, so the first prerequisite is a Java development and runtime environment.
The second prerequisite is Java-based distributed applications, as opposed to C++/CORBA applications. Examples include applications developed using the distributed computing framework that accompanies popular Java application servers such as Gemstone/J, ObjectSpace's Voyager, the WebLogic server, and others. EJB applications are, of course, distributed applications. Enterprise JavaBeans are often deployed in EJB-only servers, or in EJB-capable Java application servers.
Third, if not provided by the existing distributed computing software, you must have a JMS implementation. Note that some Java application servers include JMS; hence, they provide virtually seamless access to JMS functionality.
10) Where would I use JMS software?
JMS-based communication is a potential solution in any distributed computing scenario in which you need to pass data, either synchronously or asynchronously, among distributed software components. A distributed component can subscribe to specific topics, or connect to specific queues, and then act accordingly when qualifying messages arrive.
JMS can be an important tool for both e-commerce and e-business applications. Any enterprise computing strategy that calls for middleware solutions that function as glue and/or communication pathways among legacy applications is a potential candidate for JMS-based distributed software components. It is straightforward to write distributed components, for example, Enterprise JavaBeans that interface with legacy applications. These legacy-software-managing Enterprise JavaBeans can send legacy-related data among themselves via JMS middleware.
11) Why is JMS important?
There are several reasons. First, the JMS specification includes two popular messaging strategies: point-to-point and publish/subscribe. Many vendors are supporting this common framework; hence, programmers will be able to implement message-oriented operations in their distributed software that will be portable across many messaging-oriented middleware (MOM) products.
Second, JMS supports both synchronous and asynchronous message passing. In some scenarios, asynchronous messaging is essentially required; in others, it is simply more convenient than synchronous message operations; and, in general, there are scenarios for which highly structured, synchronous communication, such as remote method invocations, is just too rigid.
A third important issue is that JMS supports an event-oriented approach to message reception; event-driven programming is now widely recognized as a productive programming paradigm with which many programmers are now quite familiar.
Fourth, although the JMS specification does not require a security-related API, many JMS implementations provide extensive built-in security. Messages can be transmitted using certificates, as well as encryption. JMS implementations free the developer from many security burdens associated with distributed computing because JMS applications work through the JMS server, which provides security through administered objects. That is, beyond the application, it's possible to establish topic- and queue-based security controls for users, groups, access lists, and so on.
Relationship to Other Java Soft Enterprise APIs:
1) JDBC:
JMS clients may also use JDBC. They may desire to include the use of both
JDBC and JMS in the same transaction. In most cases, this will be achieved
automatically by implementing these clients as Enterprise JavaBeans. It will
also be possible to do this directly with JTA
2) JAVA BEANS:
JavaBeans can use a JMS session to send/receive messages. JMS itself is an API
and the interfaces it defines are not designed to be used directly as Java beans.
3) Enterprise Java Beans:
JMS will be an important resource available to EJB component developers. It
can be used in conjunction with other resources like JDBC to implement
enterprise services.
The current EJB specification defines beans that are invoked synchronously via
method calls from EJB clients. A future release of EJB will add a form of
asynchronous bean that is invoked when a JMS client sends it a message.
4) Java Transaction (JTA):
The java transaction package provides a client API for delimiting distributed
transactions and an API for accessing a resource’s ability to participate in a
distributed transaction.
A JMS client may use JTA to delimit distributed transactions; however, this is a
function of the transaction environment the client is running in. It is not a
Feature of JMS per se.
A JMS provider can optionally support distributed transactions via JTA.
5) Java Transaction Service (JTS):
JMS can be used in conjunction with JTS to form distributed transactions that
combine message sends and receives with database updates and other JTS
aware services. This should be handled automatically when a JMS client is run
From within an application server such as an Enterprise JavaBeans server;
However, it is also possible for JMS clients to program this explicitly.
1.4.6 Java Naming and Directory Service (JNDI)
JMS clients look up configured JMS objects using JNDI. JMS administrator’s use
provider specific facilities for creating and configuring these objects.
This division of work maximizes the portability of clients by delegating
provider specific work to the administrator. It also leads to more administrable
applications because clients do not need to embed administrative values in
their code.
GLOSSORY
JMS
Java Message Service, part of the J2EE (Java 2 Enterprise Edition) suite, developed by Sun Microsystem, provides standard APIs that Java developers can use to access the common features of enterprise message systems.
Byte Code
Java bytecode is the form of instructions that the Java virtual machine executes. Each bytecode instruction is one byte in length (hence the name),
Bytecode is the intermediate representation of Java programs just as assembler is the intermediate representation of C or C++ programs.
The bytecode is your program. Regardless of a JIT or Hotspot runtime, the bytecode is an important part of the size and execution speed of your code.
The bytecode is platform-independent code that can be sent to any platform and run on that platform.
EDI
Electronic Data Interchange (EDI) is a set of standards for structuring information to be electronically exchanged between and within businesses, organizations, government entities and other groups. The standards describe structures that emulate documents, for example purchase orders to automate purchasing. The term EDI is also used to refer to the implementation and operation of systems and processes for creating, transmitting, and receiving EDI documents.
· JIT Compiler
In the Java programming language and environment, a just-in-time (JIT) compiler is a program that turns Java bytecode (a program that contains instructions that must be interpreted) into instructions that can be sent directly to the processor. After you've written a Java program, the source language statements are compiled by the Java compiler into bytecode rather than into code that contains instructions that match a particular hardware platform's processor (for example, an Intel Pentium microprocessor or an IBM System/390 processor). The just-in-time compiler comes with the virtual machine and is used optionally. It compiles the bytecode into platform-specific executable code that is immediately executed. Sun Microsystems suggests that it's usually faster to select the JIT compiler option, especially if the method executable is repeatedly reused.
JVM
A Java Virtual Machine (JVM), is a virtual machine that interprets and executes Java bytecode.
XML
Extensible Markup Language (XML) is a simple, very flexible text format derived from SGML (ISO 8879). Originally designed to meet the challenges of large-scale electronic publishing, XML is also playing an increasingly important role in the exchange of a wide variety of data on the Web and elsewhere.
· EAI
Enterprise Application Integration (EAI) is defined as the uses of software and computer systems architectural principles to integrate a set of enterprise computer applications.
· JNDI
The Java Naming and Directory Interface (JNDI) is part of the Java platform, providing applications based on Java technology with a unified interface to multiple naming and directory services. You can build powerful and portable directory-enabled applications using this industry standard.
· LDAP
In computer networking, the Lightweight Directory Access Protocol, or LDAP is a networking protocol for querying and modifying directory services running over TCP/IP. An LDAP directory often reflects various political, geographic, and/or organizational boundaries, depending on the model chosen. LDAP deployments today tend to use Domain Name System (DNS) names for structuring the topmost levels of the hierarchy. Deeper inside the directory might appear entries representing people, organizational units, printers, documents, groups of people or anything else which represents a given tree entry (or multiple entries).
· CORBA
CORBA is the acronym for Common Object Request Broker Architecture, OMG's open, vendor-independent architecture and infrastructure that computer applications use to work together over networks. Using the standard protocol IIOP, a CORBA-based program from any vendor, on almost any computer, operating system, programming language, and network, can interoperate with a CORBA-based program from the same or another vendor, on almost any other computer, operating system, programming language, and network.
Some people think that CORBA is the only specification that OMG produces, or that the term "CORBA" covers all of the OMG specifications. Neither is true;
Remote Method Invocation (RMI)
Java Remote Method Invocation (Java RMI) enables the programmer to create distributed Java technology-based to Java technology-based applications, in which the methods of remote Java objects can be invoked from other Java virtual machines, possibly on different hosts. RMI uses object serialization to marshal and unmarshal parameters and does not truncate types, supporting true object-oriented polymorphism.
REFERENCES
Book
[1] Richard Monson – Haefel & David A.Chappell, JAVA Message Service .
O’REILLY, January 2001.
World Wide Web
[2] http://www.jguru.com/index.jsp
[3] The Stock Trader JMS Application by Gopalan Suresh Raj.htm
[4] Sun's official JMS site includes documentation, FAQs and a JMS vendor list.java.sun.com/products/jms/
[5] The Java Message Service (JMS) Tutorial is provided as a companion to the Java 2, Enterprise Edition (J2EE) SDK, version 1.3.1. java.sun.com/products/jms/tutorial/
[6] JMS implementation or an ... en.wikipedia.org/wiki/Java_Message_Service
[7] jGuru's dynamic FAQ for JMS www.jguru.com/faq/JMS
[8] JMS is a leading candidate for providing robust enterprise messaging to Web services. This article demonstrates a loosely coupled Web service with JMS.www.onjava.com/pub/a/onjava/2002/06/19/jms.html
[9] From David Gelernter's "Truth, Beauty, and the Virtual Machine," Discover Magazine, September 1997, p. 72.
Messaging systems are used to build highly reliable, scalable, and flexible distributed applications.
Distributed applications are proliferating, as are a host of previously unexplored problems of synchronization, reliability, scalability, and security. One solution is a Messaging System built from loosely coupled components communicating through messages.
2.1. What is a Messaging System?
In its essence, a messaging system allows separate, uncoupled applications to reliably communicate asynchronously. The messaging system architecture generally replaces the client/server model with a peer-to-peer relationship between individual components, where each peer can send and receive messages to and from other peers.
Messaging systems provide a host of powerful advantages over other, more conventional distributed computing models. Primarily, they encourage "loose coupling" between message consumers and message producers.
This permits dynamic, reliable, and flexible systems to be built, whereby entire ensembles of sub-applications can be modified without affecting the rest of the system.
Other advantages of messaging systems include high scalability (commercial implementations boast the ability to support tens of thousands of clients and tens of thousands of operations per second), easy integration into heterogeneous networks, and reliability due to lack of a single point of failure.
Because of the reliable and scalable nature of messaging systems, they are used to solve many business and computing science problems. For example, they are the basis of such diverse applications as workflow, network management, communication services (voice over IP, voicemail, pager, email), customer care, weather forecasting, supply chain management, and many other systems. In addition, messaging systems are also invaluable as "glue" to bring together the disparate systems that inevitably result from mergers and acquisitions.
2.2. Messaging:
In general, messaging (also called electronic messaging) is the creation, storage, exchange, and management of text, images, voice, telex, fax, e-mail, paging, and Electronic Data Interchange (EDI) over a communications network.
In programming, messaging is the exchange of messages (specially-formatted data describing events, requests, and replies) to a messaging server, which acts as a message exchange program for client programs.
There are two major messaging server models: the point-to-point model and the publish/subscribe model. Messaging allows programs to share common message-handling code, to isolate resources and interdependencies, and to easily handle an increase in message volume. Messaging also makes it easier for programs to communicate across different programming environments (languages, compilers, and operating systems) since the only thing that each environment needs to understand is the common messaging format and protocol.
IBM's MQSeries and Sun Microsystems Java Message Service (JMS) are examples of products that provide messaging interfaces and services.
2.3. What is message passing?
Message passing is a general term for a variety of strategies for high-level, structured interclient communication. For example, a mobile agent framework could provide classes and methods with which two agents (on two different computers) send each other message. JMS supports the message passing strategies, i.e. point-to-point and publish/subscribe. JMS can be utilized by any (Java-based) distributed software components; of course, the JMS middleware must be available.
2.4. Enterprise messaging systems:
The Java Message Service was developed by Sun Microsystems to provide a means for
Java programs to access enterprise messaging systems.
Enterprise messaging systems, often known as message oriented middleware (MOM),
provide a mechanism for integrating applications in a loosely coupled, flexible manner. They provide asynchronous delivery of data between applications on a store and forward basis;
That is, the applications do not communicate directly with each other, but instead
communicate with the MOM, which acts as an intermediary.
The MOM provides assured delivery of messages (or at least makes its best effort) and
relieves application programmers from knowing the details of remote procedure calls (RPC) and networking/communications protocols.
2.5. Messaging flexibility:
Let, Application A communicates with Application B by sending a message through the MOM's application programming interface (API).
The MOM routes the message to Application B, which may exist on a completely different computer; the MOM handles the network communications. If the network connection is not available, the MOM will store the message until the connection becomes available, and then forward it to Application B.
Another aspect of flexibility is that Application B may not even be executing when Application A sends its message. The MOM will hold the message until Application B begins execution and attempts to retrieve its messages. This also prevents Application A from blocking while it waits for Application B to receive the message.
This asynchronous communication requires applications to be designed somewhat differently than most are designed today, but it can be an extremely useful method for
Time-independent or parallel processing.
2.6 Loose coupling:
The real power of enterprise messaging systems lies in the loose coupling.
In the previous example, Application A sends its messages indicating a particular destination, for example "order processing." Today, Application B provides order processing capabilities.
But, in the future, we can replace Application B with a different order-processing program, and Application A will be none the wiser. It will continue to send its messages to "order processing" and the messages will continue to be processed.
Likewise, we could replace Application A, and as long as the replacement continued to send messages for "order processing," the order-processing program would not need to know there is a new application sending orders.
3: JMS
3.1. JMS API:
The JMS API is provided in the Java package javax.jms.
3.2. What is API (Application Program Interface)?
An application program interface is the specific method prescribed by a computer operating system or by an application program by which a programmer writing an application program can make requests of the operating system or another application.
An API can be contrasted with a graphical user interface or a command interface (both of which are direct user interfaces) as interfaces to an operating system or a program.
3.3 Java Message Service (JMS):
Java Message Service, part of the J2EE (Java 2 Enterprise Edition) suite, provides standard APIs that Java developers can use to access the common features of enterprise message systems. The Java Message Service (JMS) API is an enterprise messaging tool for building enterprise applications. By combining Java technology with enterprise messaging, the JMS API provides a common provider framework that enables the development of portable, message based applications
Java Message Service (JMS) is a specification for message passing and related operations among distributed software components. JMS vendors implement the specification, providing the requisite API library, plus a broker, or server, that handles message passing among clients. Programmers then implement applications that communicate with each other by way of the vendor's JMS software.
Sun's JMS provides a common interface to standard messaging protocols and also to special messaging services in support of Java programs. Sun advocates the use of the Java Message Service for anyone developing Java applications, which can be run from any major operating system platform.
The messages involved exchange crucial data between computers - rather than between users - and contain information such as event notification and service requests. Messaging is often used to coordinate programs in dissimilar systems or written in different programming languages.
Using the JMS interface, a programmer can invoke the messaging services of IBM's MQSeries, Progress Software's SonicMQ, and other popular messaging product vendors. In addition, JMS supports messages that contain serialized Java objects and messages that contain Extensible Markup Language (XML) pages.
Message queuing systems form the front-line interface between businesses (B2B) and for Enterprise Application Integration (EAI). As such, message queuing systems are often called "middleware" because they operate in the middle -- between other systems and between enterprises.
Figur 3.3.1. Messaging Sevice.
The heck with hub-and-spoke designs: Enterprises are better off doing their integrating at the edges of their networks.
3.4. JMS objectives:
There are many enterprise messaging products on the market today, and several of the
companies that produce these products were involved in the development of JMS.
These existing systems vary in capability and functionality. The authors knew that JMS would be too complicated and unwieldy if it incorporated all of the features of all existing systems.
Likewise, they believed that they could not limit themselves to only the features that all of the systems had in common.
The authors believed that it was important that JMS include all of the functionality required to implement "sophisticated enterprise applications."
3.5 The objectives of JMS:
Define a common set of messaging concepts and facilities.
Minimize the concepts a programmer must learn to use enterprise messaging.
Maximize the portability of messaging applications.
Minimize the work needed to implement a provider.
Provide client interfaces for both point-to-point and pub/sub domains.
"Domains" is the JMS term for the messaging models
APPLICATIONS OF JMS
Simple Chat example
Book warehouse example
Stock trader application
Web Logic JMS application
We will develop the simple chat example in detail:
4.1. The Chat Application:
Internet chat provides an interesting application for learning about the JMS pub/sub-messaging model. Used mostly for entertainment, web-based chat applications can be found on thousands of web sites. In a chat application, people join virtual chat rooms where they can "chat" with a group of other people.
To illustrate how JMS works, we will use the JMS pub/sub API to build a simple chat application. The requirements of Internet chat map neatly onto the publish-and-subscribe messaging model. In this model, a producer can send a message to many consumers by delivering the message to a single topic. A message producer is also called a publisher and a message consumer is also called a subscriber. The following source code is a JMS-based chat client. Every participant in a chat session uses this Chat program to join a specific chat room (topic), and deliver and receive messages to and from that room: package chap2.chat;import javax.jms.*;import javax.naming.*;import java.io.*;import java.io.InputStreamReader;import java.util.Properties; public class Chat implements javax.jms.MessageListener{ private TopicSession pubSession; private TopicSession subSession; private TopicPublisher publisher; private TopicConnection connection; private String username; /* Constructor. Establish JMS publisher and subscriber */ public Chat(String topicName, String username, String password) throws Exception { // Obtain a JNDI connection Properties env = new Properties( ); // ... specify the JNDI properties specific to the vendor InitialContext jndi = new InitialContext(env); // Look up a JMS connection factory TopicConnectionFactory conFactory = (TopicConnectionFactory)jndi.lookup("TopicConnectionFactory"); // Create a JMS connection TopicConnection connection = conFactory.createTopicConnection(username,password); // Create two JMS session objects TopicSession pubSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); TopicSession subSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); // Look up a JMS topic Topic chatTopic = (Topic)jndi.lookup(topicName); // Create a JMS publisher and subscriber TopicPublisher publisher = pubSession.createPublisher(chatTopic); TopicSubscriber subscriber = subSession.createSubscriber(chatTopic); // Set a JMS message listener subscriber.setMessageListener(this); // Intialize the Chat application set(connection, pubSession, subSession, publisher, username); // Start the JMS connection; allows messages to be delivered connection.start( ); } /* Initialize the instance variables */ public void set(TopicConnection con, TopicSession pubSess, TopicSession subSess, TopicPublisher pub, String username) { this.connection = con; this.pubSession = pubSess; this.subSession = subSess; this.publisher = pub; this.username = username; } /* Receive message from topic subscriber */ public void onMessage(Message message) { try { TextMessage textMessage = (TextMessage) message; String text = textMessage.getText( ); System.out.println(text); } catch (JMSException jmse){ jmse.printStackTrace( ); } } /* Create and send message using topic publisher */ protected void writeMessage(String text) throws JMSException { TextMessage message = pubSession.createTextMessage( ); message.setText(username+" : "+text); publisher.publish(message); } /* Close the JMS connection */ public void close( ) throws JMSException { connection.close( ); } /* Run the Chat client */ public static void main(String [] args){ try{ if (args.length!=3) System.out.println("Topic or username missing"); // args[0]=topicName; args[1]=username; args[2]=password Chat chat = new Chat(args[0],args[1],args[2]); // Read from command line BufferedReader commandLine = new java.io.BufferedReader(new InputStreamReader(System.in)); // Loop until the word "exit" is typed while(true){ String s = commandLine.readLine( ); if (s.equalsIgnoreCase("exit")){ chat.close( ); // close down connection System.exit(0);// exit program } else chat.writeMessage(s); } } catch (Exception e){ e.printStackTrace( ); } }}
4.2. Getting Started with the Chat Example:
To put this client to use, we have to compile it like any other Java program. Then start our JMS server, setting up topics, usernames, and passwords, as we want. Configuration of a JMS server is vendor-dependent.
The Chat class includes a main() method so that it can be run as a standalone Java application. It's executed from the command line as follows:java chap2.chat.Chat topic username password
The topic is the destination that we want to publish-and-subscribe to; username and password make up the authentication information for the client. We have to Run at least two chat clients in separate command windows and try typing into one; we should see the text type displayed by the other client.
The chat client creates a JMS publisher and subscriber for a specific topic. The topic represents the chat room. The JMS server registers all the JMS clients that want to publish or subscribe to a specific topic. When text is entered at the command line of one of the chat clients, it is published to the messaging server. The messaging server identifies the topic associated with the publisher and delivers the message to all the JMS clients that have subscribed to that topic.
Figure 4.2.1. The chat client
4.3. Bootstrapping the JMS client:
The main() method bootstraps the chat client and provides a command-line interface. Once an instance of the Chat class is created, the main() method spends the rest of its time reading text typed at the command line and passing it to the Chat instance using the instance's writeMessage() method.
The Chat instance connects to the topic and receives and delivers messages. The Chat instance starts its life in the constructor, which does all the work to connect to the topic and set up the TopicPublisher and TopicSubscribers for delivering and receiving messages.
4.4. Obtaining a JNDI connection:
The chat client starts by obtaining a JNDI connection to the JMS messaging server. JNDI is an implementation-independent API for directory and naming systems. A directory service provides JMS clients with access to ConnectionFactory and Destinations (topics and queues) objects. ConnectionFactory and Destination objects are the only things in JMS that cannot be obtained using the JMS API--unlike connections, sessions, producers, consumers, and messages, which are manufactured using the JMS API. JNDI provides a convenient, location-transparent, configurable, and portable mechanism for obtaining ConnectionFactory and Destination objects, also called JMS administered objects because they are established and configured by a system administrator.
Using JNDI, a JMS client can obtain access to a JMS provider by first looking up a ConnectionFactory. The ConnectionFactory is used to create JMS connections, which can then be used for sending and receiving messages. Destination objects, which represent virtual channels (topics and queues) in JMS, are also obtained via JNDI and are used by the JMS client. The directory service can be configured by the system administrator to provide JMS administered objects so that the JMS clients don't need to use proprietary code to access a JMS provider.
JMS servers will either work with a separate directory service (e.g., LDAP) or provide their own directory service that supports the JNDI API. The constructor of the Chat class starts by obtaining a connection to the JNDI naming service used by the JMS server:
4.5. Understanding JNDI:
JNDI is a standard Java extension that provides a uniform API for accessing a variety of directory and naming services. In this respect, it is somewhat similar to JDBC. JDBC lets you write code that can access different relational databases such as Oracle, SQLServer, or Sybase; JNDI lets you write code that can access different directory and naming services, such as LDAP, Novell Netware NDS, CORBA Naming Service, and proprietary naming services provided by JMS servers.
In JMS, JNDI is used mostly as a naming service to locate administered objects. Administered objects are JMS objects that are created and configured by the system administrator. Administered objects include JMS ConnectionFactory and Destination objects like topics and queues.
Administered objects are bound to a name in a naming service. An example of a naming service is the DNS, which converts an Internet hostname like www.oreilly.com into a network address that browsers use to connect to web servers. There are many other naming services, such as COSNaming in CORBA and the Java RMI registry. Naming services allow printers, distributed objects, and JMS administered objects to be bound to names and organized in a hierarchy similar to a filesystem. A directory service is a more sophisticated kind of naming service.
JNDI provides an abstraction that hides the specifics of the naming service, making client applications more portable. Using JNDI, JMS clients can browse a naming service and obtain references to administered objects without knowing the details of the naming service or how it is implemented. JMS servers are usually be used in combination with a standard JNDI driver (a.k.a. service provider) and directory service like LDAP, or provide a proprietary JNDI service provider and directory service.
JNDI is both virtual and dynamic. It is virtual because it allows one naming service to be linked to another. Using JNDI, we can drill down through directories to files, printers, JMS administered objects, and other resources following virtual links between naming services. The user doesn't know or care where the directories are actually located. As an administrator, you can create virtual directories that span a variety of different services over many different physical locations.
JNDI is dynamic because it allows the JNDI drivers for specific types of naming and directory services to be loaded dynamically at runtime. A driver maps a specific kind of naming or directory service into the standard JNDI class interfaces. // Obtain a JNDI connectionProperties env = new Properties( );// ... specify the JNDI properties specific to the vendor InitialContext undid = new InitialContext(env);
Creating a connection to a JNDI naming service requires that a javax.naming.InitialContext object be created. An InitialContext is the starting point for any JNDI lookup--it's similar in concept to the root of a filesystem. The InitialContext provides a network connection to the directory service that acts as a root for accessing JMS administered objects. The properties used to create an InitialContext depend on which JMS directory service you are using. The code used to create a JNDI InitialContext in BEA's Weblogic naming service, for example, would look something like this: Properties env = new Properties( );env.put(Context.SECURITY_PRINCIPAL, "guest"); env.put(Context.SECURITY_CREDENTIALS, "guest");env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");env.put(Context.PROVIDER_URL, "t3://localhost:7001"); InitialContext jndi = new InitialContext(env);
When SonicMQ is used in combination with a third party LDAP directory service, the connection properties would be very different. For example, the following shows how a SonicMQ JMS client would use JNDI to access JMS administered objects stored in a LDAP directory server:Properties env = new Properties( );env.put(Context.SECURITY_PRINCIPAL, "guest"); env.put(Context.SECURITY_CREDENTIALS, "guest");env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=acme.com"); InitialContext jndi = new InitialContext(env);
The TopicConnectionFactory:
Once a JNDI InitialContext object is instantiated, it can be used to look up the TopicConnectionFactory in the messaging server's naming service: TopicConnectionFactory conFactory = (TopicConnectionFactory)jndi.lookup("TopicConnectionFactory");
The javax.jms.TopicConnectionFactory is used to manufacture connections to a message server. A TopicConnectionFactory is a type of administered object, which means that its attributes and behavior are configured by the system administrator responsible for the messaging server. The TopicConnectionFactory is implemented differently by each vendor. Connection factory might, for example, be configured to manufacture connections that use a particular protocol, security scheme, clustering strategy, etc. A system administrator might choose to deploy several different TopicConnectionFactory objects, each configured with its own JNDI lookup name.
The TopicConnectionFactory provides two overloaded versions of the createTopicConnection( ) method: package javax.jms; public interface TopicConnectionFactory extends ConnectionFactory { public TopicConnection createTopicConnection( ) throws JMSException, JMSSecurityException; public TopicConnection createTopicConnection(String username, String password) throws JMSException, JMSSecurityException;}
These methods are used to create TopicConnection objects. The behavior of the no-arg method depends on the JMS provider. Some JMS providers will assume that the JMS client is connecting under anonymous security context, while other providers may assume that the credentials can be obtained from JNDI or the current thread. The second method provides the client with a username-password authentication credential, which can be used to authenticate the connection. In our code, we choose to authenticate the connection explicitly with a username and password.
4.6. The TopicConnection:
The TopicConnection is created by the TopicConnectionFactory : // Look up a JMS connection factoryTopicConnectionFactory conFactory = (TopicConnectionFactory)jndi.lookup("TopicConnectionFactory"); // Create a JMS connection TopicConnection connection = conFactory.createTopicConnection(username, password);
The TopicConnection represents a connection to the message server. Each TopicConnection that is created from a TopicConnectionFactory is a unique connection to the server. JMS client might choose to create multiple connections from the same connection factory, but this is rare as connections are relatively expensive (each connection requires a network socket, I/O streams, memory, etc.). Creating multiple Session objects (discussed later in this chapter) from the same connection is considered more efficient, because sessions share access to the same connection. The TopicConnection is an interface that extends javax.jms.Connection interface. It defines several general-purpose methods used by clients of the TopicConnection. Among these methods are the start( ), stop( ), and close( ) methods: // javax.jms.Connection the super interfacepublic interface Connection { public void start() throws JMSException; public void stop() throws JMSException; public void close() throws JMSException; ...} // javax.jms.TopicConnection extends javax.jms.Connectionpublic interface TopicConnection extends Connection { public TopicSession createTopicSession(boolean transacted, int acknowledgeMode) throws JMSException; ...}
The start(), stop(), and close() methods allow a client to manage the connection directly. The start() method turns the inbound flow of messages "on," allowing messages to be received by the client. This method is used at the end of the constructor in Chat class: ... // Intialize the Chat application set(connection, pubSession, subSession, publisher, username); connection.start( ); }
It is a good idea to start the connection after the subscribers have been set up, because the messages start to flow in from the topic as soon as start() is invoked.
The stop( ) method blocks the flow of inbound messages until the start( ) method is invoked again. The close( ) method is used to close the TopicConnection to the message server. This should be done when a client is finished using the TopicConnection; closing the connection conserves resources on the client and server. In the Chat class, the main( ) method calls Chat.close( ) when "exit" is typed at the command line. The Chat.close( ) method in turn calls the TopicConnection.close( ) method: public void close( ) throws JMSException { connection.close( );}
Closing a TopicConnection closes all the objects associated with the connection including the TopicSession, TopicPublisher, and TopicSubscriber.
4.7. The TopicSession:
After the TopicConnection is obtained, it's used to create TopicSession objects: // Create a JMS connectionTopicConnection connection =conFactory.createTopicConnection(username,password); // Create two JMS session objectsTopicSession pubSession =connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);TopicSession subSession =connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
A TopicSession object is a factory for creating Message, TopicPublisher, and TopicSubscriber objects. A client can create multiple TopicSession objects to provide more granular control over publishers, subscribers, and their associated transactions. In this case we create two TopicSession objects, pubSession and subSession.
The boolean parameter in the createTopicSession( ) method indicates whether the Session object will be transacted. A transacted Session automatically manages outgoing and incoming messages within a transaction. The second parameter indicates the acknowledgment mode used by the JMS client. An acknowledgment is a notification to the message server that the client has received the message. In this case we chose AUTO_ACKNOWLEDGE, which means that the message is automatically acknowledged after it is received by the client.
The TopicSession objects are used to create the TopicPublisher and TopicSubscriber. The TopicPublisher and TopicSubscriber objects are created with a Topic identifier and are dedicated to the TopicSession that created them; they operate under the control of a specific TopicSession: TopicPublisher publisher = pubSession.createPublisher(chatTopic);TopicSubscriber subscriber = subSession.createSubscriber(chatTopic);
The TopicSession is also used to create the Message objects that are delivered to the topic. The pubSession is used to create Message objects in the writeMessage( ) method. When you type text at the command line, the main( ) method reads the text and passes it to the Chat instance by invoking writeMessage( ). The writeMessage( ) method (shown in the following example) uses the pubSession object to generate a TextMessage object that can be used to deliver the text to the topic: protected void writeMessage(String text) throws JMSException{ TextMessage message = pubSession.createTextMessage( ); message.setText(username+" : "+text); publisher.publish(message);}
Several Message types can be created by a TopicSession. The most commonly used type is the TextMessage.
4.8. The Topic:
JNDI is used to locate a Topic object, which is an administered object like the TopicConnectionFactory : InitialContext jndi = new InitialContext(env);..// Look up a JMS topicTopic chatTopic = (Topic)jndi.lookup(topicName);
A Topic object is a handle or identifier for an actual topic, called a physical topic, on the messaging server. A physical topic is an electronic channel to which many clients can subscribe and publish. A topic is analogous to a news group or list server: when a message is sent to a news group or list server, it is delivered to all the subscribers. Similarly, when a JMS client delivers a Message object to a topic, all the clients subscribed to that topic receive the Message.
The Topic object encapsulates a vendor-specific name for identifying a physical topic in the messaging server. The Topic object has one method, getName( ), which returns the name identifier for the physical topic it represents. The name encapsulated by a Topic object is vendor-specific and varies from product to product. For example, one vendor might use dot (".") separated topic names, like "oreilly.jms.chat", while another vendor might use a completely different naming system, similar to LDAP naming, "o=oreilly,cn=chat". Using topic names directly will result in client applications that are not portable across brands of JMS servers. The Topic object hides the topic name from the client, making the client more portable.
As a convention, we'll refer to a physical topic as a topic and only use the term "physical topic" when it's important to stress its difference from a Topic object.
4.9. The TopicPublisher:
A TopicPublisher was created using the pubSession and the chatTopic: // Look up a JMS topicTopic chatTopic = (Topic)jndi.lookup(topicName); // Create a JMS publisher and subscriber TopicPublisher publisher = pubSession.createPublisher(chatTopic);
A TopicPublisher is used to deliver messages to a specific topic on a message server. The Topic object used in the createPublisher( ) method identifies the topic that will receive messages from the TopicPublisher. In the Chat example, any text typed on the command line is passed to the Chat class's writeMessage( ) method. This method uses the TopicPublisher to deliver a message to the topic: protected void writeMessage(String text) throws JMSException{ TextMessage message = pubSession.createTextMessage( ); message.setText(username+" : "+text); publisher.publish(message);}
The TopicPublisher objects deliver messages to the topic asynchronously. Asynchronous delivery and consumption of messages is a key characteristic of Message-Oriented Middleware; the TopicPublisher doesn't block or wait until all the subscribers receive the message. Instead, it returns from the publish( ) method as soon as the message server receives the message. It's up to the message server to deliver the message to all the subscribers for that topic.
4.10. The TopicSubscriber:
The TopicSubscriber is created using the subSession and the chatTopic: // Look up a JMS topicTopic chatTopic = (Topic)jndi.lookup(topicName); // Create a JMS publisher and subscriber TopicPublisher publisher = pubSession.createPublisher(chatTopic);TopicSubscriber subscriber = subSession.createSubscriber(chatTopic);
A TopicSubscriber receives messages from a specific topic. The Topic object argument used in the createSubscriber( ) method identifies the topic from which the TopicSubscriber will receive messages.
The TopicSubscriber receives messages from the message server one at a time (serially). These messages are pushed from the message server to the TopicSubscriber asynchronously, which means that the TopicSubscriber does not have to poll the message server for messages. In our example, each chat client will receive any message published by any of the other chat clients. When a user enters text at the command line, the text message is delivered to all other chat clients that subscribe to the same topic.
The pub/sub messaging model in JMS includes an in-process Java event model for handling incoming messages. This is similar to the event-driven model used by Java beans.An object simply implements the listener interface, in this case the MessageListener, and then is registered with the TopicSubscriber. A TopicSubscriber may have only one MessageListener object. Here is the definition of the MessageListener interface used in JMS: package javax.jms; public interface MessageListener { public void onMessage(Message message);}
When the TopicSubscriber receives a message from its topic, it invokes the onMessage() method of its MessageListener objects. The Chat class itself implements the MessageListener interface and implements the onMessage() method: public class Chat implements javax.jms.MessageListener{ public void onMessage(Message message){ try{ TextMessage textMessage = (TextMessage)message; String text = textMessage.getText( ); System.out.println(text); } catch (JMSException jmse){jmse.printStackTrace( );} } ...}
The Chat class is a MessageListener type, and therefore registers itself with the TopicSubscriber in its constructor: TopicSubscriber subscriber = subSession.createSubscriber(chatTopic); subscriber.setMessageListener(this);
When the message server pushes a message to the TopicSubscriber, the TopicSubscriber invokes the Chat object's onMessage( ) method.
It's fairly easy to confuse the Java Message Service with its use of a Java event model. JMS is an API for asynchronous distributed enterprise messaging that spans processes and machines across a network. The Java event model is used to synchronously deliver events by invoking methods on one or more objects in the same process that have registered as listeners. The JMS pub/sub model uses the Java event model so that a TopicSubscriber can notify its MessageListener object in the same process that a message has arrived from the message server.
4.11. The Message:
In the chat example, the TextMessage class is used to encapsulate the messages we send and receive. A TextMessage contains a java.lang.String as its body and is the most commonly used message type. The onMessage( ) method receives TextMessage objects from the TopicSubscriber. Likewise, the writeMessage() method creates and publishes TextMessage objects using the TopicPublisher:public void onMessage(Message message){ try{ TextMessage textMessage = (TextMessage)message; String text = textMessage.getText( ); System.out.println(text); } catch (JMSException jmse){jmse.printStackTrace( );}}protected void writeMessage(String text) throws JMSException{ TextMessage message = pubSession.createTextMessage( ); message.setText(username+" : "+text); publisher.publish(message);}
A message basically has two parts: a header and payload. The header is comprised of special fields that are used to identify the message, declare attributes of the message, and provide information for routing. The difference between message types is determined largely by their payload, i.e., the type of application data the message contains. The Message class, which is the superclass of all message objects, has no payload. It is a lightweight message that delivers no payload but can serve as a simple event notification. The other message types have special payloads that determine their type and use:
Message:
This type has no payload. It is useful for simple event notification.
TextMessage:
This type carries a java.lang.String as its payload. It is useful for exchanging simple text messages and also for more complex character data, such as XML documents.
ObjectMessage:
This type carries a serializable Java object as its payload. It's useful for exchanging Java objects.
BytesMessage:
This type carries an array of primitive bytes as its payload. It's useful for exchanging data in an application's native format, which may not be compatible with other existing Message types. It is also useful where JMS is used purely as a transport between two systems, and the message payload is opaque to the JMS client.
Stream Message:
This type carries a stream of primitive Java types (int, double, char, etc.) as its payload. It provides a set of convenience methods for mapping a formatted stream of bytes to Java primitives. It's an easy programming model when exchanging primitive application data in a fixed order.
Map Message:
This type carries a set of name-value pairs as its payload. The payload is similar to a java.util.Properties object, except the values must be Java primitives their wrappers. The Map Message is useful for delivering keyed data.
4.12. Sessions and Threading:
The Chat application uses a separate session for the publisher and subscriber, pubSession and subSession, respectively. This is due to a threading restriction imposed by JMS. According to the JMS specification, a session may not be operated on by more than one thread at a time. In our example, two threads of control are active: the default main thread of the Chat application and the thread that invokes the onMessage( ) handler. The thread that invokes the onMessage( ) handler is owned by the JMS provider. Since the invocation of the onMessage( ) handler is asynchronous, it could be called while the main thread is publishing a message in the writeMessage( ) method. If both the publisher and subscriber had been created by the same session, the two threads could operate on these methods at the same time; in effect, they could operate on the same TopicSession concurrently--a condition that is prohibited.
A goal of the JMS specification was to avoid imposing an internal architecture on the JMS provider. Requiring a JMS provider's implementation of a Session object to be capable of safely handling multiple threads was specifically avoided. This is mostly due to one of the intended uses of JMS--that the JMS API be a wrapper around an existing messaging system, which may not have multithreaded delivery capabilities on the client.
The requirement imposed on the JMS provider is that the sending of messages and the asynchronous receiving of messages be processed serially. It is possible to publish-and-subscribe using the same session, but only if the application is publishing from within the onMessage( ) handler.
Finally we can summarize it in the following details:
1. Thread-specific storage is used with the Java Authentication and Authorization Service (JAAS) to allow security credentials to transparently propagate between resources and applications.
2. The actual physical network connection may or may not be unique depending on the vendor. However, the connection is considered to be logically unique so authentication and connection control can be managed separately from other connections.
3. Although the in-process event model used by TopicSubscriber is similar to the one used in Java beans, JMS itself is an API and the interfaces it defines are not Java beans.
5: JMS COMPONENT & ELEMENT
5.1. JMS elements:
JMS consists of several elements:
JMS provider:
An implementation of the JMS interface for a Message Oriented Middleware (MOM). Providers are implemented as either a Java JMS implementation or an adapter to a non-Java MOM.
JMS client:
A Java-based application or object that produces and/or consumes messages.
JMS producer:
A JMS client that creates and sends messages.
JMS consumer:
A JMS client that receives messages.
JMS message:
An object that contains the data being transferred between JMS clients.
JMS queue:
A staging area that contains messages that have been sent and are waiting to be read. As the name queue suggests, the messages are delivered in the order sent. A message is removed from the queue once it has been read.
JMS topic
A distribution mechanism for publishing messages that are delivered to multiple subscribers.
5.2. JMS models:
The JMS API supports two models:
point-to-point or queuing model
publish and subscribe model
In the point-to-point or queuing model, a producer posts messages to a particular queue and a consumer reads messages from the queue. Here, the producer knows the destination of the message and posts the message directly to the consumer's queue. It is characterized by following:
Only one consumer will get the message
The producer does not have to be running at the time the receiver consumes the message, nor does the receiver need to be running at the time the message is sent
Every message successfully processed is acknowledged by the receiver
The publish/subscribe model supports publishing messages to a particular message topic. Zero or more subscribers may register interest in receiving messages on a particular message topic. In this model, neither the publisher nor the subscriber know about each other. A good metaphor for it is anonymous bulletin board. The following are characteristics of this model:
Multiple consumers can get the message
There is a timing dependency between publishers and subscribers. Publisher has to create a subscription in order for clients to be able to subscribe. Subscriber has to remain continuously active to receive messages, unless it has established a durable subscription. In that case, messages published while the subscriber is not connected will be redistributed whenever it will reconnect.
Using Java, JMS provides a way of separating the application from the transport layer of providing data. The same Java classes can be used to communicate with different JMS providers by using the JNDI information for the desired provider. The classes first use a connection factory to connect to the queue or topic, and then use populate and send or publish the messages. On the receiving side, the clients then receive or subscribe to the messages.
Messaging systems are classified into different models that determine which client receives a message. The most common messaging models are:
· Publish-Subscribe Messaging
· Point-To-Point Messaging
· Request-Reply Messaging Not all MOM providers support all these models.
5.3. Publish-Subscribe Messaging:
When multiple applications need to receive the same messages, Publish-Subscribe Messaging is used. The central concept in a Publish-Subscribe messaging system is the Topic. Multiple Publishers may send messages to a Topic, and all Subscribers to that Topic receive all the messages sent to that Topic. This model, as shown in Figure, is extremely useful when a group of applications want to notify each other of a particular occurrence.
The point to note in Publish-Subscribe Messaging is that, there may be multiple Senders and multiple Receivers.
Figure 5.3.1. Publish-Subscribe Based Messaging System
5.4. Point-To-Point Messaging:
When one process needs to send a message to another process, Point-To-Point Messaging can be used. However, this may or may not be a one-way relationship. The client to a Messaging system may only send messages, only receive messages, or send and receive messages. At the same time, another client can also send and/or receive messages. In the simplest case, one client is the Sender of the message and the other client is the Receiver of the message.There are two basic types of Point-to-Point Messaging systems.
The first one involves a client that directly sends a message to another client. The second and more common implementation is based on the concept of a Message Queue. Such a system is shown in Figure .
Figure 5.4.1.Queue Based (Point-to-Point) Messaging System
5.5. Request-ReplyMessaging:
When an application sends a message and expects to receive a message in return, Request-Reply Messaging can be used. This is the standard synchronous object-messaging format. This messaging model is often defined as a subset of one of the other two models. JMS does not explicitly support Request-Reply Messaging, though it allows it in the context of the other methods.
5.6. Basic point-to-point data link:
A traditional point-to-point data link is a communications medium with exactly two endpoints and no data or packet formatting. The host computers at either end had to take full responsibility for formatting the data transmitted between them. The connection between the computer and the communications medium was generally implemented through an RS-232 interface, or something similar. Computers in close proximity may be connected by wires directly between their interface cards.
When connected at a distance, each endpoint would be fitted with a modem to convert analog telecommunications signals into a digital data stream. When the connection used a telecommunications provider, the connections were called a dedicated, leased, or private line. The ARPANET used leased lines to provide point-to-point data links between its packet-switching nodes, which were called Interface Message Processors.
5.7. What is point-to-point messaging?
With point-to-point message passing the sending application/client establishes a named message queue in the JMS broker/server and sends messages to this queue. The receiving client registers with the broker to receive messages posted to this queue. There is a one-to-one relationship between the sending and receiving clients.
5.8. What is publish/subscribe messaging?
With publish/subscribe message passing the sending application/client establishes a named topic in the JMS broker/server and publishes messages to this queue. The receiving clients register (specifically, subscribe) via the broker to messages by topic; every subscriber to a topic receives each message published to that topic. There is a one-to-many relationship between the publishing client and the subscribing clients.
5.9. Java Message Service (JMS) Architecture:
Figure shows the JMS Architecture. As shown in Figure, JMS Service Providers implement the JMS interface on top of their messaging services. JMS defines Queues and Topics, but it does not require the provider to implement both. JMS thus tries to maximize portability of the solution with as many features possible.
Figure 5.9.1. The Java Message Service Architecture
5.10. The primary features of JMS are as follows:
Connection Factories are used in JMS to create connections to a specific JMS provider.In JMS, both Publish-Subscribe Messaging and Point-To-Point are implemented and defined by separate interfaces so that a Provider does not have to support both.JMS defines the concept of a Topic or a Queue as the target for a Message. Topics are used for Publish-Subscribe Messaging. Queues are used for Point-to-Point Messaging. The Providers’ code is defined by interfaces in JMS, freeing the implementation from the limitations of subclassing.JMS provides support for distributed transactions.The Java Message Service APIBoth Publish-Subscribe Messaging and Point-To-Point Messaging inherit from a common set of abstract interfaces as shown in Table 1.
JMS Parent
Publish-Subscribe Domain
Point-To-Point Domain
Destination
Topic
Queue
ConnectionFactory
TopicConnectionFactory
QueueConnectionFactory
Connection
TopicConnection
QueueConnection
Session
TopicSession
QueueSession
MessageProducer
TopicPublisher
QueueSender
MessageConsumer
TopicSubscriber
QueueReceiver, QueueBrowser
Table 5.10.1. Relationship of Point-To-Point and Publish-Subscribe interfaces
6: JAVA MESAGING ENSURES DATA DELIVERY
6.1. When it absolutely, positively has to get there, a jms server may be the answer:
Here the transmission of business data is concerned, just keeping fingers crossed and hoping for the best isn't good enough. If a company has gone to the trouble of linking its distributed systems so those systems can communicate, it's a safe bet that the data actually has to get where it was meant to go. Unfortunately, communications can and do break down, and while communication failure should never jeopardize data integrity in a well-designed system, repeated rollbacks take their toll in time, system load, and user patience.
When application developers can't afford "maybe" for an answer, one technology they turn to is messaging, usually in the form of message-oriented middleware. Messaging is relatively easy to implement and gives developers a straightforward guarantee that data transmitted between two processes was in fact sent and received, and in the order in which the messages were intended.
The idea behind messaging is simple: Between two or more distributed programs that need to communicate, you install an intermediary to which these processes send data in the form of discrete, one-way packages of information. Rather than letting the processes communicate directly, the intermediary stores these information packages--messages--and forwards them to the proper destination at the proper time. The intermediary, the message broker, is responsible for ensuring that the messages are indeed sent and received.
This is called asynchronous communication, because while the processes are communicating, they aren't doing it in real time. Contrast asynchronous messaging with other distributed programming models, such as Microsoft's Distributed Component Object Model, Corba, Java Remote Method Invocation, or remote procedure calls. These models let one process simultaneously and directly send and receive data to and from another process.
One of asynchronous messaging's main advantages is that in the event of application, system, or network failure, communication between applications is not compromised, it's simply postponed. The message broker will try to send the message until it receives confirmation from the destination process that the message has arrived.
This is especially important in today's networked world, where notebook PCs or handheld devices frequently go offline or the network itself becomes unavailable. Compare this with old standby remote procedure calls, where communication fails completely if one of the services becomes unavailable.
"The gorgeous thing about messaging is that it is so fundamentally simple," says George Kassabgi, VP of marketing and sales for Progress Software Corp. "I believe it is possible to successfully explain messaging to a 12-year-old."
Developers involved in application integration have been quick to latch onto the simplicity of messaging. Venerable message-oriented middleware products such as IBM's MQSeries have long been a staple of enterprise application integration projects.
Until recently, however, Java developers have not had a portable application programming interface for message-based communications, nor have independent software vendors had a standard Java messaging specification to work to. Fortunately for them, Sun Microsystems in mid-1998 rolled out the Java Message Service to fulfill those needs. The company is including JMS in its Java 2, Enterprise Edition, platform
Increasingly, developers are favoring products based on the JMS API in lieu of more tried-and-true messaging fare. JMS has inspired a number of messaging products, including SonicMQ from Progress Software, FioranoMQ by Fiorano Software, and Sun's Java Message Queue, set to be released by year's end.
Java application server vendors are also building JMS compatibility into their products as part of their efforts to attain Java 2, Enterprise Edition, compliance. These vendors include BEA Systems Inc. and Bluestone Software Inc.
6.2. What JMS cannot provide?
The following features, common in MOM products, are not addressed by the JMS
specification. While acknowledged by the JMS authors as important for the development of robust messaging applications, these features are considered JMS provider-specific.
JMS providers are free to implement these features in any manner they please, if at all:
Load balancing and fault tolerance
Error and advisory system messages and notification
Administration
Security
Wire protocol
Message type repository
Load Balancing/Fault Tolerance –
Many products provide support for multiple, cooperating clients implementing a critical service. The JMS API does not specify how such clients cooperate to appear to be a single, unifiedservice.
Error/Advisory Notification –
Most messaging products define system messages that provide asynchronous notification of problems or system events to clients. JMS does not attempt to standardize these messages. By following the guidelines defined by JMS, clients can avoid using these messages and thus prevent the portability problems their use introduces.
Administration –
JMS does not define an API for administering messagingproducts.
Security –
JMS does not specify an API for controlling the privacy and integrity of messages. It also does not specify how digital signatures or keys
are distributed to clients. Security is considered to be a JMS provider specific feature that is configured by an administrator rather than controlled via the JMS API by clients.
7: SOME ISSUES REGARDING JMS
1) Are there other messaging frameworks that use Java technology?
Yes. Prior to JMS, Java software for various distributed computing environments, for example, the WebLogic server, the Aglet framework for mobile agents, SoftWired's iBus software, and many others have provided a variety of message-oriented, interclient communication solutions for enterprise computing. In many cases, the messaging functionality is part of a larger distributed computing framework.
2) Does JMS support distributed transactions?
Distributed transaction services are provided via the Java Transaction API (JTA). JMS does not mandate JTA support. See the JMS vendor's documentation for JTA-related discussion, especially, whether or not the vendor supports JTA.
3) Does JMS provide load balancing, fault tolerance, scalability, and so on?
The JMS specification does not address these issues; hence, vendors are free to implement their own support, and many vendors do provide these services.
4) How does JMS compare to peer-to-peer distributed computing?
The term peer-to-peer is used in a variety of ways in distributed and network computing. One usage, at the application level, is to describe a distributed application scenario in with each distributed component potentially interacts with every other distributed component and maintains a network reference (access) to each component (using any of several mechanisms to do so, for example, via Enterprise JavaBeans and EJB servers resident on each network host, via simple RMI-based communication among applications, and so on).
With JMS, distributed components interact with the JMS broker via destinations (topics and queues), which then disseminates messages to the registered clients; thus, distributed components do not have to know (and manage) each others' network locations. As for the JMS middleware, it can use (behind the scenes) any of several network topologies, for example, bus, ring, hierarchical, fully connected (peer-to-peer), star (hub-and-spoke), or others, including hybrids.
Messaging systems are peer-to-peer distributed systems in the sense that, at least potentially, every (registered) client can communicate with every other (registered) client.
5) Is it possible for a client to send multiple messages and ensure that the entire set of messages is delivered?
The preferred method for handling interdependent messages is to produce them within a transacted session. See Session.commit(), Session.rollback(), and XASession.
Is it possible for server-side applications, for example, a JMS application, to play the role of a resource in a distributed transaction?
Under certain conditions, yes. In this particular case, the JMS server would have to implement the appropriate resource-related interfaces in javax.transaction.xa so that the JTS transaction manager can enlist the JMS server as an intermediary, playing the role of a resource manager with respect to the JMS application.
6) Is it possible to use transacted sessions with other Java-technology, transaction-processing facilities, for example, JTA?
No. It is possible (if provided by the JMS implementation) to use JTA in the context of a session, but not a transacted session. That is, you cannot use Session.commit() and Session.rollback() in a context that's controlled by an instance of UserTransaction.
If, for example, one or more messages, in conjunction with database operations, all form a "logical transactional unit," it's usually best to take advantage of the transaction support provided by the JDBC driver, possibly augmenting this transacted (database) server operation with, javax.transaction.UserTransaction from the Java Transaction API (JTA), if JTA is implemented by the JMS server. Note that JMS implementations vary in their support for distributed transaction processing. See the javax.jms.XA... interfaces in the API documentation.
7) What else is missing from JMS?
The answer depends on your point of view. From one point of view, nothing is missing. In terms of common distributed computing-related functionality, typically present in larger Java application servers, JMS does not mandate functionality related to the following:
Administration
Error, or system event, notification
Load balancing, scalability
Low-level transport protocol
Security
8) What is the role of the JMS server? Why is it necessary?
The server, message broker, or whatever it is called, functions as an intermediary. Suppose a distributed component wants to send (financial) stock information to one or more remotely located distributed components. Rather than having to know the exact clients to which it sends messages containing stock information, it can establish either a message queue or a message topic area (depending on the message-passing scheme, point-to-point or publish/subscribe) with the JMS server and "post" the stock information with the server, which then distributes the messages to the appropriately registered receiving clients.
Also, without this intermediary, the sending client would have the burden of monitoring whether or not the receiving client is currently connected, whether or not a network failure occurred during the send operation, and so on. The server plays an important role in transparently handling many network-related issues, including reliable message delivery, which can require transaction processing and/or persistent message storage.
9) What software do I need in order to add JMS message passing to my enterprise exists distributed applications?
The "J" in JMS stands for Java, so the first prerequisite is a Java development and runtime environment.
The second prerequisite is Java-based distributed applications, as opposed to C++/CORBA applications. Examples include applications developed using the distributed computing framework that accompanies popular Java application servers such as Gemstone/J, ObjectSpace's Voyager, the WebLogic server, and others. EJB applications are, of course, distributed applications. Enterprise JavaBeans are often deployed in EJB-only servers, or in EJB-capable Java application servers.
Third, if not provided by the existing distributed computing software, you must have a JMS implementation. Note that some Java application servers include JMS; hence, they provide virtually seamless access to JMS functionality.
10) Where would I use JMS software?
JMS-based communication is a potential solution in any distributed computing scenario in which you need to pass data, either synchronously or asynchronously, among distributed software components. A distributed component can subscribe to specific topics, or connect to specific queues, and then act accordingly when qualifying messages arrive.
JMS can be an important tool for both e-commerce and e-business applications. Any enterprise computing strategy that calls for middleware solutions that function as glue and/or communication pathways among legacy applications is a potential candidate for JMS-based distributed software components. It is straightforward to write distributed components, for example, Enterprise JavaBeans that interface with legacy applications. These legacy-software-managing Enterprise JavaBeans can send legacy-related data among themselves via JMS middleware.
11) Why is JMS important?
There are several reasons. First, the JMS specification includes two popular messaging strategies: point-to-point and publish/subscribe. Many vendors are supporting this common framework; hence, programmers will be able to implement message-oriented operations in their distributed software that will be portable across many messaging-oriented middleware (MOM) products.
Second, JMS supports both synchronous and asynchronous message passing. In some scenarios, asynchronous messaging is essentially required; in others, it is simply more convenient than synchronous message operations; and, in general, there are scenarios for which highly structured, synchronous communication, such as remote method invocations, is just too rigid.
A third important issue is that JMS supports an event-oriented approach to message reception; event-driven programming is now widely recognized as a productive programming paradigm with which many programmers are now quite familiar.
Fourth, although the JMS specification does not require a security-related API, many JMS implementations provide extensive built-in security. Messages can be transmitted using certificates, as well as encryption. JMS implementations free the developer from many security burdens associated with distributed computing because JMS applications work through the JMS server, which provides security through administered objects. That is, beyond the application, it's possible to establish topic- and queue-based security controls for users, groups, access lists, and so on.
Relationship to Other Java Soft Enterprise APIs:
1) JDBC:
JMS clients may also use JDBC. They may desire to include the use of both
JDBC and JMS in the same transaction. In most cases, this will be achieved
automatically by implementing these clients as Enterprise JavaBeans. It will
also be possible to do this directly with JTA
2) JAVA BEANS:
JavaBeans can use a JMS session to send/receive messages. JMS itself is an API
and the interfaces it defines are not designed to be used directly as Java beans.
3) Enterprise Java Beans:
JMS will be an important resource available to EJB component developers. It
can be used in conjunction with other resources like JDBC to implement
enterprise services.
The current EJB specification defines beans that are invoked synchronously via
method calls from EJB clients. A future release of EJB will add a form of
asynchronous bean that is invoked when a JMS client sends it a message.
4) Java Transaction (JTA):
The java transaction package provides a client API for delimiting distributed
transactions and an API for accessing a resource’s ability to participate in a
distributed transaction.
A JMS client may use JTA to delimit distributed transactions; however, this is a
function of the transaction environment the client is running in. It is not a
Feature of JMS per se.
A JMS provider can optionally support distributed transactions via JTA.
5) Java Transaction Service (JTS):
JMS can be used in conjunction with JTS to form distributed transactions that
combine message sends and receives with database updates and other JTS
aware services. This should be handled automatically when a JMS client is run
From within an application server such as an Enterprise JavaBeans server;
However, it is also possible for JMS clients to program this explicitly.
1.4.6 Java Naming and Directory Service (JNDI)
JMS clients look up configured JMS objects using JNDI. JMS administrator’s use
provider specific facilities for creating and configuring these objects.
This division of work maximizes the portability of clients by delegating
provider specific work to the administrator. It also leads to more administrable
applications because clients do not need to embed administrative values in
their code.
GLOSSORY
JMS
Java Message Service, part of the J2EE (Java 2 Enterprise Edition) suite, developed by Sun Microsystem, provides standard APIs that Java developers can use to access the common features of enterprise message systems.
Byte Code
Java bytecode is the form of instructions that the Java virtual machine executes. Each bytecode instruction is one byte in length (hence the name),
Bytecode is the intermediate representation of Java programs just as assembler is the intermediate representation of C or C++ programs.
The bytecode is your program. Regardless of a JIT or Hotspot runtime, the bytecode is an important part of the size and execution speed of your code.
The bytecode is platform-independent code that can be sent to any platform and run on that platform.
EDI
Electronic Data Interchange (EDI) is a set of standards for structuring information to be electronically exchanged between and within businesses, organizations, government entities and other groups. The standards describe structures that emulate documents, for example purchase orders to automate purchasing. The term EDI is also used to refer to the implementation and operation of systems and processes for creating, transmitting, and receiving EDI documents.
· JIT Compiler
In the Java programming language and environment, a just-in-time (JIT) compiler is a program that turns Java bytecode (a program that contains instructions that must be interpreted) into instructions that can be sent directly to the processor. After you've written a Java program, the source language statements are compiled by the Java compiler into bytecode rather than into code that contains instructions that match a particular hardware platform's processor (for example, an Intel Pentium microprocessor or an IBM System/390 processor). The just-in-time compiler comes with the virtual machine and is used optionally. It compiles the bytecode into platform-specific executable code that is immediately executed. Sun Microsystems suggests that it's usually faster to select the JIT compiler option, especially if the method executable is repeatedly reused.
JVM
A Java Virtual Machine (JVM), is a virtual machine that interprets and executes Java bytecode.
XML
Extensible Markup Language (XML) is a simple, very flexible text format derived from SGML (ISO 8879). Originally designed to meet the challenges of large-scale electronic publishing, XML is also playing an increasingly important role in the exchange of a wide variety of data on the Web and elsewhere.
· EAI
Enterprise Application Integration (EAI) is defined as the uses of software and computer systems architectural principles to integrate a set of enterprise computer applications.
· JNDI
The Java Naming and Directory Interface (JNDI) is part of the Java platform, providing applications based on Java technology with a unified interface to multiple naming and directory services. You can build powerful and portable directory-enabled applications using this industry standard.
· LDAP
In computer networking, the Lightweight Directory Access Protocol, or LDAP is a networking protocol for querying and modifying directory services running over TCP/IP. An LDAP directory often reflects various political, geographic, and/or organizational boundaries, depending on the model chosen. LDAP deployments today tend to use Domain Name System (DNS) names for structuring the topmost levels of the hierarchy. Deeper inside the directory might appear entries representing people, organizational units, printers, documents, groups of people or anything else which represents a given tree entry (or multiple entries).
· CORBA
CORBA is the acronym for Common Object Request Broker Architecture, OMG's open, vendor-independent architecture and infrastructure that computer applications use to work together over networks. Using the standard protocol IIOP, a CORBA-based program from any vendor, on almost any computer, operating system, programming language, and network, can interoperate with a CORBA-based program from the same or another vendor, on almost any other computer, operating system, programming language, and network.
Some people think that CORBA is the only specification that OMG produces, or that the term "CORBA" covers all of the OMG specifications. Neither is true;
Remote Method Invocation (RMI)
Java Remote Method Invocation (Java RMI) enables the programmer to create distributed Java technology-based to Java technology-based applications, in which the methods of remote Java objects can be invoked from other Java virtual machines, possibly on different hosts. RMI uses object serialization to marshal and unmarshal parameters and does not truncate types, supporting true object-oriented polymorphism.
REFERENCES
Book
[1] Richard Monson – Haefel & David A.Chappell, JAVA Message Service .
O’REILLY, January 2001.
World Wide Web
[2] http://www.jguru.com/index.jsp
[3] The Stock Trader JMS Application by Gopalan Suresh Raj.htm
[4] Sun's official JMS site includes documentation, FAQs and a JMS vendor list.java.sun.com/products/jms/
[5] The Java Message Service (JMS) Tutorial is provided as a companion to the Java 2, Enterprise Edition (J2EE) SDK, version 1.3.1. java.sun.com/products/jms/tutorial/
[6] JMS implementation or an ... en.wikipedia.org/wiki/Java_Message_Service
[7] jGuru's dynamic FAQ for JMS www.jguru.com/faq/JMS
[8] JMS is a leading candidate for providing robust enterprise messaging to Web services. This article demonstrates a loosely coupled Web service with JMS.www.onjava.com/pub/a/onjava/2002/06/19/jms.html
[9] From David Gelernter's "Truth, Beauty, and the Virtual Machine," Discover Magazine, September 1997, p. 72.