The sample application is a simple JMS application that acts as a JMS client that produces and consumes messages using the Pub/Sub messaging model. The client looks up a topic named myTopic, and a topic connection factory TCFactory.
The JNDI initial context factory and the provider URL will be passed into the application as commandline arguments. To explain the various options available the following configuration will be used to store the Administered objects:
For MQ and MQSeries JMS the Administered objects will be stored in the WinNT file system context and looked up using JNDI
For SonicMQ the Administered objects will be stored in a standalone LDAP server and looked up using JNDI
For iBus//MessageServer, FioranoMQ, and WebLogic the Administered objects will be stored in their internal JNDI compliant namespace and looked up using JNDI
The client will create appropriate connections, sessions, producers and consumers for producing and consuming messages. The JNDI provider URL and the name of the initial context factory are passed as command-line arguments:
import javax.jms.Topic; import javax.jms.TopicConnectionFactory; import javax.jms.TopicConnection; import javax.jms.TopicSession; import javax.jms.TopicPublisher; import javax.jms.TopicSubscriber; import javax.jms.JMSException; import javax.jms.TextMessage; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import java.util.Properties; public class PortableJMSClient {
The JNDI names of the Administered objects are stored in two class variables. The topic is called myTopic and the topic connection factory is called TCFactory:
public static final String TOPIC_FACTORY = "TCFactory"; public static final String TOPIC = "myTopic";
First an instance of java.util.Properties is created and stored with the following JNDI environment values:
The JNDI provider URL. This depends on the JNDI service provider implementation used for storing the Administered objects.
The JNDI initial context factory:
For JMQ and MQSeries JMS we use Sun's initial context factory for file system context
For SonicMQ we use Sun's LDAP initial context factory
For FioranoMQ and iBus//MessageServer the initial context factory that comes with the server is used
And for WebLogic the T3 initial context factory is used
The two parameters mentioned above are passed to the program as command-line arguments:
public static void main(String args[]) throws NamingException, JMSException { Properties prop = new Properties(); if(args.length == 2) { //Add the initial context factory prop.put (Context. INITIAL_CONTEXT_FACTORY, args [0]); //Add the provider URL prop.put (Context.PROVIDER_URL, args[1]); } //Create the initial context Context ctx = new InitialContext (prop); //Create an instance PortableJMSClient client = new PortableJMSClient(); //Publish and subscribe messages using Pub\Sub client.doPubSub(ctx); //Close initial context ctx.close(); } private void doPubSub(Context ctx) throws NamingException, JMSException { //Lookup the topic Topic topic = (Topic)ctx.lookup(TOPIC); //Lookup the topic connection factory TopicConnectionFactory tcFactory = (TopicConnectionFactory)ctx.lookup(TOPIC_FACTORY); //Create topic connection TopicConnection tCon = tcFactory.createTopicConnection(); //Create topic session TopicSession tSes = tCon.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE); //Create topic publisher TopicPublisher publisher = tSes.createPublisher(topic); //Create topic subscriber TopicSubscriber subscriber = tSes.createSubscriber(topic); //Start queue connection tCon.start();
A text message is created using the topic session and is published using the message publisher. The same message is then received by the topic subscriber:
TextMessage msg = tSes.createTextMessage(); System.out.println("Publishing message on the topic"); //Send message publisher.publish(msg); //Receive message msg = (TextMessage)subscriber.receive(); System.out.println("Received message from the topic"); //Close queue connection tCon.close(); } }
There are four main steps in running the client explained above:
Compile the class listed in the last section
Store the Administered objects myTopic and TCFactory in the namespace of a JNDI service provider implementation
Start the message server
Run the client
The first step is the same for all the four JMS implementations. The second and third steps are specific to the JMS provider used. Even though the fourth step is also common for all the JMS providers, we will be passing different command-line parameters for the JNDI service provider URL and initial context factory depending on the JNDI service provider implementation used for storing the Administered objects.
Apart from the JDK standard edition classes, we need the JMS and JNDI classes. The JNDI classes/interfaces are available in JDK 1.3 standard edition (although it doesn't cover the full implementation of JNDI 1.2.1). The JMS classes/interfaces are available in the j2ee.jar file available with J2EE SDK 1.2.1, but will almost certainly also be available with your provider installation, as will most of the libraries you need to use them.