Configure JMS Client using GlassFish 3

I have taken Theoretical concepts from http://docs.oracle.com/javaee/1.3/jms/tutorial/1_3_1-fcs/doc/overview.html#1027335 with a little modifications.

What Is Messaging ?

Messaging is a method of communication between software components or applications. A messaging system is a peer-to-peer facility: A messaging client can send messages to, and receive messages from, any other client. Each client connects to a messaging agent that provides facilities for creating, sending, receiving, and reading messages.

What Is the JMS API?

The Java Message Service is a Java API that allows applications to create, send, receive, and read messages.

The JMS API enables communication that is not only loosely coupled but also

Asynchronous – A JMS provider can deliver messages to a client as they arrive; a client does not have to request messages in order to receive them.
Reliable – The JMS API can ensure that a message is delivered once and only once. Lower levels of reliability are available for applications that can afford to miss messages or to receive duplicate messages.

When Can We Use the JMS API?

An enterprise application provider is likely to choose a messaging API over a tightly coupled API, such as Remote Procedure Call (RPC), under the following circumstances.

The provider wants the components not to depend on information about other components’ interfaces, so that components can be easily replaced.
The provider wants the application to run whether or not all components are up and running simultaneously.
The application business model allows a component to send information to another and to continue to operate without receiving an immediate response.

Messaging Domains
Point-to-Point Messaging Domain

A point-to-point (PTP) product or application is built around the concept of message queues, senders, and receivers. Each message is addressed to a specific queue, and receiving clients extract messages from the queue(s) established to hold their messages. Queues retain all messages sent to them until the messages are consumed or until the messages expire.

Publish/Subscribe Messaging Domain

In a publish/subscribe (pub/sub) product or application, clients address messages to a topic. Publishers and subscribers are generally anonymous and may dynamically publish or subscribe to the content hierarchy. The system takes care of distributing the messages arriving from a topic’s multiple publishers to its multiple subscribers. Topics retain messages only as long as it takes to distribute them to current subscribers.

Pub/sub messaging has the following characteristics.

Each message may have multiple consumers.
Publishers and subscribers have a timing dependency. A client that subscribes to a topic can consume only messages published after the client has created a subscription, and the subscriber must continue to be active in order for it to consume messages.

Message Consumption

Synchronously – A subscriber or a receiver explicitly fetches the message from the destination by calling the receive method. The receive method can block until a message arrives or can time out if a message does not arrive within a specified time limit.
Asynchronously – A client can register a message listener with a consumer. A message listener is similar to an event listener. Whenever a message arrives at the destination, the JMS provider delivers the message by calling the listener’s onMessage method, which acts on the contents of the message.

Message Bodies

Message TypeBody Contains
TextMessageA java.lang.String object (for example, the contents of an Extensible Markup Language file).
MapMessageA set of name/value pairs, with names as String objects and values as primitive types in the Java programming language.
The entries can be accessed sequentially by enumerator or randomly by name. The order of the entries is undefined.
BytesMessageA stream of uninterpreted bytes. This message type is for literally encoding a body to match an existing message format.
StreamMessageA stream of primitive values in the Java programming language, filled and read sequentially.
ObjectMessageA Serializable object in the Java programming language.
MessageNothing. Composed of header fields and properties only. This message type is useful when a message body is not required.

Administered Objects

Two parts of a JMS application–destinations and connection factories–are best maintained administratively rather than programmatically.

Connection Factories

A connection factory is the object a client uses to create a connection with a provider. A connection factory encapsulates a set of connection configuration parameters that has been defined by an administrator.

For JMS client program, we need to perform a JNDI API lookup of the connection factory. For example,

Queue connection factory

InitialContext initialContext = new InitialContext();
        QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory) initialContext
                    .lookup("jms/QueueConnectionFactory");

 
Topic connection factory

InitialContext initialContext = new InitialContext();
        TopicConnectionFactory topicConnectionFactory = (TopicConnectionFactory) initialContext
                    .lookup("jms/TopicConnectionFactory");

 
Queue or Topic connection factory

InitialContext initialContext = new InitialContext();
        ConnectionFactory connectionFactory = (ConnectionFactory) initialContext
                    .lookup("jms/ConnectionFactory");

 

Calling the InitialContext() method without any parameter results in a search of the current classpath for a vendor-specific file named jndi.properties. This file indicates which JNDI API implementation to use and which namespace to use.

Destinations

A destination is the object a client uses to specify the target of messages it produces and the source of messages it consumes.

In point-to-point messaging domain, destinations are called queues and in publish/subscribe messaging domain, destinations are called topics.

In addition to looking up a connection factory, we need to look up a destination like queue or topic.

For example, the following line of code performs a JNDI API lookup of the Topic

Topic topic = (Topic) initialContext.lookup("jms/Topic");

 
The following line of code performs a JNDI API lookup of the Queue

Queue queue = (Queue) initialContext.lookup("jms/Queue");

 
Connections

A connection encapsulates a virtual connection with a JMS provider. A connection could represent an open TCP/IP socket between a client and a provider service daemon. We use a connection to create one or more sessions.

Like connection factories, connections come in three forms, implementing either the QueueConnection or the TopicConnection interface or Connection interface for both Queue or Topic. For example, once we have a QueueConnectionFactory or a TopicConnectionFactory or ConnectionFactory object, we can use it to create a connection:

Queue connection

QueueConnection queueConnection =
          queueConnectionFactory.createQueueConnection();

 
Topic connection

TopicConnection topicConnection =
          topicConnectionFactory.createTopicConnection();

 
Queue or Topic connection

Connection connection = connectionFactory.createConnection();

 

Before our application consumes messages, we must call the connection’s start method.

When an application completes, we need to close the connections to release the resources held by the JMS provider. Closing a connection also closes its sessions and their message producers and message consumers.

Close queue connection

queueConnection.close();

 
Close topic connection

topicConnection.close();

 
Close queue or topic connection

connection.close();

 
We can call stop method to stop message delivery temporarily without closing the connection.
Sessions

A session is a single-threaded context for producing and consuming messages. We use sessions to create message producers, message consumers, and messages.

A session provides a transactional context with which to group a set of sends and receives into an atomic unit of work.

Sessions come in three forms, implementing either the QueueSession, the TopicSession or the Session interface.

For example, for a TopicConnection object, we use it to create a TopicSession:

TopicSession topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);

 

The first argument means that the session is not transacted; the second means that the session automatically acknowledges messages when they have been received successfully.

Similarly, we use a QueueConnection object to create a QueueSession:

 QueueSession queueSession = queueConnection.createQueueSession(true, 0);

 

Here, the first argument means that the session is transacted; the second indicates that message acknowledgment is not specified for transacted sessions.

For a QueueConnection or TopicConnection, we can use below example

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

 
or

 Session session = connection.createSession(true, 0);

 
Message Producers

A message producer is an object created by a session and is used for sending messages to a destination. The point-to-point form of a message producer implements the QueueSender interface. The publish/subscribe form implements the TopicPublisher interface.

For example, we use a QueueSession to create a sender for the queue, and we use a TopicSession to create a publisher for the topic:

QueueSender queueSender = queueSession.createSender(queue);

 

TopicPublisher topicPublisher = topicSession.createPublisher(topic);

 

Once a message producer is created then we can use it to send messages. With a QueueSender, we use the send method:

queueSender.send(message);

 
With a TopicPublisher, we use the publish method:

 topicPublisher.publish(message);

 

We can also use session and MessageProducer to send/publish messages to queue/topic using below example

For a queue

MessageProducer messageProducer = session.createProducer(queue);
    TextMessage textMessage = session.createTextMessage();
    messageProducer.send(textMessage);

 
For a topic

MessageProducer messageProducer = session.createProducer(topic);
    TextMessage textMessage = session.createTextMessage();
    messageProducer.send(textMessage);

 
Message Consumers

A message consumer is an object created by a session and is used for receiving messages sent to a destination. A message consumer allows a JMS client to register interest in a destination with a JMS provider. The JMS provider manages the delivery of messages from a destination to the registered consumers of the destination.

The point-to-point form of message consumer implements the QueueReceiver interface. The publish/subscribe form implements the TopicSubscriber interface.

For example, we use a QueueSession to create a receiver for the queue, and a TopicSession to create a subscriber for the topic:

QueueReceiver queueReceiver = queueSession.createReceiver(queue);
TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic);

 

We use the TopicSession.createDurableSubscriber method to create a durable topic subscriber. For details http://docs.oracle.com/javaee/1.3/jms/tutorial/1_3_1-fcs/doc/advanced.html#1024758

Once a message consumer has been created, it becomes active, and we can use it to receive messages. We can use the close method for a QueueReceiver or a TopicSubscriber to make the message consumer inactive. Message delivery does not begin until we start the connection by calling the start method.

With either a QueueReceiver or a TopicSubscriber, we use the receive method to consume a message synchronously. We can use this method at any time after calling the start method:

queueConnection.start();
    TextMessage textMessage = (TextMessage) queueReceiver.receive();

 

topicConnection.start();
    TextMessage textMessage = (TextMessage) queueReceiver.receive();
    TextMessage textMessage = (TextMessage) topicSubscriber.receive(5000); // wait for five soconds for the message and time out after five seconds
    TextMessage textMessage = (TextMessage) queueReceiver.receiveNoWait(); // do not wait for the message, if message found then get it

 
Message Listeners

A message listener is an object that acts as an asynchronous event handler for messages. This object implements the MessageListener interface, which contains one method, onMessage. In the onMessage method, we define the actions to be taken when a message arrives.

We register the message listener with a specific QueueReceiver or TopicSubscriber by using the setMessageListener method. For example, if we define a class named TopicListener that implements the MessageListener interface, we can register the message listener as follows:

TopicListener topicListener = new TopicListener();
topicSubscriber.setMessageListener(topicListener);

 

After registering the message listener, we call the start method on the QueueConnection or the TopicConnection to begin message delivery.

Once message delivery begins, the message consumer automatically calls the message listener’s onMessage method whenever a message is delivered. The onMessage method takes one argument of type Message, which the method can cast to any of the other message types.

A message listener is not specific to a particular destination type. The same listener can obtain messages from either a queue or a topic, depending on whether the listener is set by a QueueReceiver or a TopicSubscriber object. A message listener does, however, usually expect a specific message type and format. Moreover, if it needs to reply to messages, a message listener must either assume a particular destination type or obtain the destination type of the message and create a producer for that destination type.

Your onMessage method should handle all exceptions. It must not throw checked exceptions, and throwing a RuntimeException, though possible, is considered a programming error.

The session used to create the message consumer serializes the execution of all message listeners registered with the session. At any time, only one of the session’s message listeners is running.

We will not discuss more on Theoretical part rather we will look into the practical example here.

Prerequisites
JDK 1.6
GlassFish 3.0.5
Eclipse/Netbeans IDE
Jar Files
JMS Client in GlassFish Server

This example has been tested with GlassFish 3.0.5 but if you want to test with higher versions like GlassFish 3.1.2 or GlassFish 4.0 then you can do that, only requirement is you need to replace the jar files by the GlassFish version jar files.

You have seen a list of jar files need to be put in the classpath as I have mentioned in the above screen-shot, all the jar files are taken from the GlassFish server directory mainly from glassfishxx/glassfish/modules, glassfishxx/glassfish/lib, glassfishxx/glassfish/mq/lib and glassfishxx/glassfish/modules/endorsed.

glassfishxx – here xx denotes the version for the GlassFish server.

Starting the GlassFish Server

  • Open cmd(command) prompt in Windows
  • Go to directory glassfishv3\glassfish\bin
  • Execute command – asadmin start-domain domain1

Once the server gets successfully started then you will see the message something like following:

Waiting for DAS to start ...............
    Started domain: domain1
    Domain location: <installation drive>:\glassfishv3\glassfish\domains\domain1
    Log file: <installation drive>:\glassfishv3\glassfish\domains\domain1\logs\server.log
    Admin port for the domain: 4848
    Command start-domain executed successfully.

 
Login to Admin Console
Now open the URL http://localhost:4848 and login using username/password if you had given username/password while installing GlassFish server
Creating Connection Factories
Go to Resources -> JMS Resources -> Connection Factories
Pool Name: “jms/ConnectionFactory”
Resource Type: “javax.jms.ConnectionFactory”
Description: optional field
Status: “Enabled”
Click ‘OK’
JMS Client in GlassFish Server
Creating Destination Resources
Go to Resources -> JMS Resources -> Destination Factories
Destination – Queue
JNDI Name: “jms/Queue”
Physical Destination Name: jmsQueue. Do not put any “/” in a word – will not work.
Resource Type: “javax.jms.Queue”
Description: optional field
Status: “Enabled”
Click ‘OK’
JMS Client in GlassFish Server
Destination – Topic
JNDI Name: “jms/Topic”
Physical Destination Name: jmsTopic. Do not put any “/” in a word – will not work.
Resource Type: “javax.jms.Topic”
Description: optional field
Status: “Enabled”
Click ‘OK’
JMS Client in GlassFish Server
Point-to-Point Example

In point-to-point we will have a JNDI connection factory, a queue, a producer and a consumer.

We will create Producer.java, Consumer.java, AsynchronousConsumer.java, QueueMessageListener.java and MessageQueueBrowser.java

Producer.java – will produce message and send to the queue
Consumer.java – synchronously consume the message from the queue
AsynchronousConsumer.java – asynchronously consume the message from the queue. It will use QueueMessageListener.java for asynchronously receiving message
MessageQueueBrowser.java – will give you how many messages are there in the queue.

Note: If the message(s) is/are consumed by a consumer then there will be no message in the queue because we know that for point-to-point communication there will be always one producer communicate with only one consumer at a time or vise versa.

Producer.java

package in.webtuts.jms.queue;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.JMSException;
    import javax.jms.MessageProducer;
    import javax.jms.Queue;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import javax.naming.InitialContext;
    public class Producer {
        /**
         * @param args
         *            the command line arguments
         */
        public static void main(String[] args) {
            ConnectionFactory connectionFactory = null;
            Connection connection = null;
            Session session = null;
            MessageProducer messageProducer = null;
            try {
                InitialContext initialContext = new InitialContext();
                connectionFactory = (ConnectionFactory) initialContext
                        .lookup("jms/ConnectionFactory");
                System.out.println("connectionFactory: " + connectionFactory);
                Queue queue = (Queue) initialContext.lookup("jms/Queue");
                System.out.println("queue: " + queue);
                connection = connectionFactory.createConnection();
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                messageProducer = session.createProducer(queue);
                TextMessage textMessage = session.createTextMessage();
                textMessage.setText("Can we meet today ?");
                System.out.println("Sending the following message: "
                        + textMessage.getText());
                messageProducer.send(textMessage);
                textMessage.setText("Do you read me ?");
                System.out.println("Sending the following message: "
                        + textMessage.getText());
                messageProducer.send(textMessage);
                textMessage.setText("Have a good Day!");
                System.out.println("Sending the following message: "
                        + textMessage.getText());
                messageProducer.send(textMessage);
            } catch (Exception ex) {
                Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null,
                        ex);
            } finally {
                try {
                    if (messageProducer != null) {
                        messageProducer.close();
                    }
                    if (session != null) {
                        session.close();
                    }
                    if (connection != null) {
                        connection.close();
                    }
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 
Consumer.java

package in.webtuts.jms.queue;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.JMSException;
    import javax.jms.MessageConsumer;
    import javax.jms.Queue;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import javax.naming.InitialContext;
    public class Consumer {
        /**
         * @param args
         *            the command line arguments
         */
        public static void main(String[] args) {
            ConnectionFactory connectionFactory = null;
            Connection connection = null;
            Session session = null;
            MessageConsumer messageConsumer = null;
            try {
                InitialContext initialContext = new InitialContext();
                connectionFactory = (ConnectionFactory) initialContext
                        .lookup("jms/ConnectionFactory");
                System.out.println("connectionFactory: " + connectionFactory);
                Queue queue = (Queue) initialContext.lookup("jms/Queue");
                System.out.println("queue: " + queue);
                connection = connectionFactory.createConnection();
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                messageConsumer = session.createConsumer(queue);
                connection.start();
                boolean goodByeReceived = false;
                while (!goodByeReceived) {
                    TextMessage textMessage = (TextMessage) messageConsumer
                            .receive();
                    if (textMessage.getText() != null
                            && textMessage.getText().equals("Good bye!")) {
                        goodByeReceived = true;
                    }
                    System.out.println("Waiting for messages...");
                    if (textMessage != null) {
                        System.out.print("Received the following message: ");
                        System.out.println(textMessage.getText());
                        System.out.println();
                    }
                }
            } catch (Exception ex) {
                Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null,
                        ex);
            } finally {
                try {
                    if (messageConsumer != null) {
                        messageConsumer.close();
                    }
                    if (session != null) {
                        session.close();
                    }
                    if (connection != null) {
                        connection.close();
                    }
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 
AsynchronousConsumer.java

package in.webtuts.jms.queue;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.JMSException;
    import javax.jms.MessageConsumer;
    import javax.jms.Queue;
    import javax.jms.Session;
    import javax.naming.InitialContext;
    public class AsynchronousConsumer {
        /**
         * @param args
         *            the command line arguments
         */
        public static void main(String[] args) {
            ConnectionFactory connectionFactory = null;
            Connection connection = null;
            Session session = null;
            MessageConsumer messageConsumer = null;
            try {
                InitialContext initialContext = new InitialContext();
                connectionFactory = (ConnectionFactory) initialContext
                        .lookup("jms/ConnectionFactory");
                System.out.println("connectionFactory: " + connectionFactory);
                Queue queue = (Queue) initialContext.lookup("jms/Queue");
                System.out.println("queue: " + queue);
                connection = connectionFactory.createConnection();
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                messageConsumer = session.createConsumer(queue);
                messageConsumer
                        .setMessageListener(new QueueMessageListener());
                connection.start();
                Thread.sleep(1000);
            } catch (Exception ex) {
                Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null,
                        ex);
            } finally {
                try {
                    if (messageConsumer != null) {
                        messageConsumer.close();
                    }
                    if (session != null) {
                        session.close();
                    }
                    if (connection != null) {
                        connection.close();
                    }
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 
QueueMessageListener.java

package in.webtuts.jms.queue;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.TextMessage;
    public class QueueMessageListener implements javax.jms.MessageListener {
        @Override
        public void onMessage(Message message) {
            try {
                TextMessage textMessage = (TextMessage) message;
                System.out.print("Received the following message: ");
                System.out.println(textMessage.getText());
                System.out.println();
            } catch (JMSException ex) {
                Logger.getLogger(AsynchronousConsumer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

 
MessageQueueBrowser.java

package in.webtuts.jms.queue;
    import java.util.Enumeration;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.JMSException;
    import javax.jms.Queue;
    import javax.jms.QueueBrowser;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import javax.naming.InitialContext;
    public class MessageQueueBrowser {
        /**
         * @param args
         *            the command line arguments
         */
        public static void main(String[] args) {
            ConnectionFactory connectionFactory = null;
            Connection connection = null;
            Session session = null;
            QueueBrowser queueBrowser = null;
            try {
                InitialContext initialContext = new InitialContext();
                connectionFactory = (ConnectionFactory) initialContext
                        .lookup("jms/ConnectionFactory");
                System.out.println("connectionFactory: " + connectionFactory);
                Queue queue = (Queue) initialContext.lookup("jms/Queue");
                System.out.println("queue: " + queue);
                connection = connectionFactory.createConnection();
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                queueBrowser = session.createBrowser(queue);
                @SuppressWarnings("rawtypes")
                Enumeration enumeration = queueBrowser.getEnumeration();
                if (enumeration != null) {
                    if (!enumeration.hasMoreElements()) {
                        System.out.println("There are no messages "
                                + "in the queue.");
                    } else {
                        System.out
                                .println("The following messages are in the queue:");
                        while (enumeration.hasMoreElements()) {
                            TextMessage textMessage = (TextMessage) enumeration
                                    .nextElement();
                            System.out.println(textMessage.getText());
                        }
                    }
                }
            } catch (Exception ex) {
                Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null,
                        ex);
            } finally {
                try {
                    if (queueBrowser != null) {
                        queueBrowser.close();
                    }
                    if (session != null) {
                        session.close();
                    }
                    if (connection != null) {
                        connection.close();
                    }
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 
Now test the application and see the ouput carefully at each run.
1. run the MessageQueueBrowser.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@364ef
    queue: GlassFish(tm) MQ Destination
    getName():        jmsQueue
    Class:            com.sun.messaging.Queue
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsQueue, imqDestinationDescription=A Description for the Destination Object}
    There are no messages in the queue.

 
From the above output we see that there is no message in the queue initially.
2. run the Producer.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@e56328
    queue: GlassFish(tm) MQ Destination
    getName():        jmsQueue
    Class:            com.sun.messaging.Queue
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsQueue, imqDestinationDescription=A Description for the Destination Object}
    Sending the following message: Can we meet today ?
    Sending the following message: Do you read me ?
    Sending the following message: Have a good Day!

 
So above output says that three messages have been sent to the queue.
3. run the MessageQueueBrowser.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@1d0eb0b
    queue: GlassFish(tm) MQ Destination
    getName():        jmsQueue
    Class:            com.sun.messaging.Queue
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsQueue, imqDestinationDescription=A Description for the Destination Object}
    The following messages are in the queue:
    Can we meet today ?
    Do you read me ?
    Have a good Day!

 
So above output says that three messages available in the queue.
4. run the Consumer.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@e56328
    queue: GlassFish(tm) MQ Destination
    getName():        jmsQueue
    Class:            com.sun.messaging.Queue
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsQueue, imqDestinationDescription=A Description for the Destination Object}
    Waiting for messages...
    Received the following message: Can we meet today ?
    Waiting for messages...
    Received the following message: Do you read me ?
    Waiting for messages...
    Received the following message: Have a good Day!

 
So we have got three messages from the queue.
5. run the MessageQueueBrowser.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@f72e77
    queue: GlassFish(tm) MQ Destination
    getName():        jmsQueue
    Class:            com.sun.messaging.Queue
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsQueue, imqDestinationDescription=A Description for the Destination Object}
    There are no messages in the queue.

 
Now we don’t have any message in the queue because all three messages have been consumed by the consumer in the previous step.
6. run the Producer.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@119ca2c
    queue: GlassFish(tm) MQ Destination
    getName():        jmsQueue
    Class:            com.sun.messaging.Queue
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsQueue, imqDestinationDescription=A Description for the Destination Object}
    Sending the following message: Can we meet today ?
    Sending the following message: Do you read me ?
    Sending the following message: Have a good Day!

 
Again producer has sent three messages to the queue.
7. run the MessageQueueBrowser.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@1d0eb0b
    queue: GlassFish(tm) MQ Destination
    getName():        jmsQueue
    Class:            com.sun.messaging.Queue
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsQueue, imqDestinationDescription=A Description for the Destination Object}
    The following messages are in the queue:
    Can we meet today ?
    Do you read me ?
    Have a good Day!

 
So above output says that three messages available in the queue.
8. run the AsynchronousConsumer.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@142c63f
    queue: GlassFish(tm) MQ Destination
    getName():        jmsQueue
    Class:            com.sun.messaging.Queue
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsQueue, imqDestinationDescription=A Description for the Destination Object}
    Received the following message: Can we meet today ?
    Received the following message: Do you read me ?
    Received the following message: Have a good Day!

 

We have seen that consumer has got three messages from the queue. We have onMessage() method in AsynchronousConsumer class so whenever a message comes to the queue that message is automatically consumed by the consumer. Also notice that we have Thread.sleep(1000) in AsynchronousConsumer class so that there is a few delay between connection and message received.

9. run the MessageQueueBrowser.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@1d0eb0b
    queue: GlassFish(tm) MQ Destination
    getName():        jmsQueue
    Class:            com.sun.messaging.Queue
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsQueue, imqDestinationDescription=A Description for the Destination Object}
    There are no messages in the queue.

 

Again the queue is empty because all three messages have been consumed by the consumer asynchronously in the previous step.

Publish/Subscribe Example

In publish/subscribe we will have a JNDI connection factory, a topic, one or more publisher, one or more consumer.

We will create Publisher.java, SubscriberOne.java, SubscriberTwo.java, AsynchronousSubscriber.java and TopicMessageListener.java

Publisher.java – will produce message and send to the queue
SubscriberOne.java – synchronously consume the message from the queue
SubscriberTwo.java – synchronously consume the message from the queue
AsynchronousSubscriber.java – asynchronously consume the message from the queue. It will use TopicMessageListener.java for asynchronously receiving message

In this example I have created one publisher and two subscriber for synchronously receiving messages because the relationship between publisher and subscriber are one-to-many, many-to-many and many-to-one.

I ahve also created AsynchronousSubscriber class for asynchronously receiving the messages from the Topic.

Note: If the message(s) is/are consumed by a consumer then message(s) will be there because there may be multiple publishers and multiple subscriber participate in the communication. All subscriber must be active before a publisher publishes the message to the Topic.

Publisher.java

package in.webtuts.jms.topic;
    import in.webtuts.jms.queue.Producer;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.JMSException;
    import javax.jms.MessageProducer;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import javax.jms.Topic;
    import javax.naming.InitialContext;
    public class Publisher {
        /**
         * @param args
         *            the command line arguments
         */
        public static void main(String[] args) {
            ConnectionFactory connectionFactory = null;
            Connection connection = null;
            Session session = null;
            MessageProducer messageProducer = null;
            try {
                InitialContext initialContext = new InitialContext();
                connectionFactory = (ConnectionFactory) initialContext
                        .lookup("jms/ConnectionFactory");
                System.out.println("connectionFactory: " + connectionFactory);
                Topic topic = (Topic) initialContext.lookup("jms/Topic");
                System.out.println("Topic: " + topic);
                connection = connectionFactory.createConnection();
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                messageProducer = session.createProducer(topic);
                TextMessage textMessage = session.createTextMessage();
                textMessage.setText("Can we meet today ?");
                System.out.println("Sending the following message: "
                        + textMessage.getText());
                messageProducer.send(textMessage);
                textMessage.setText("Do you read me ?");
                System.out.println("Sending the following message: "
                        + textMessage.getText());
                messageProducer.send(textMessage);
                textMessage.setText("Have a good Day!");
                System.out.println("Sending the following message: "
                        + textMessage.getText());
                messageProducer.send(textMessage);
            } catch (Exception ex) {
                Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null,
                        ex);
            } finally {
                try {
                    if (messageProducer != null) {
                        messageProducer.close();
                    }
                    if (session != null) {
                        session.close();
                    }
                    if (connection != null) {
                        connection.close();
                    }
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 
SubscriberOne.java

package in.webtuts.jms.topic;
    import in.webtuts.jms.queue.Producer;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.JMSException;
    import javax.jms.MessageConsumer;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import javax.jms.Topic;
    import javax.naming.InitialContext;
    public class SubscriberOne {
        /**
         * @param args
         *            the command line arguments
         */
        public static void main(String[] args) {
            ConnectionFactory connectionFactory = null;
            Connection connection = null;
            Session session = null;
            MessageConsumer messageConsumer = null;
            try {
                InitialContext initialContext = new InitialContext();
                connectionFactory = (ConnectionFactory) initialContext
                        .lookup("jms/ConnectionFactory");
                System.out.println("connectionFactory: " + connectionFactory);
                Topic topic = (Topic) initialContext.lookup("jms/Topic");
                System.out.println("Topic: " + topic);
                connection = connectionFactory.createConnection();
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                messageConsumer = session.createConsumer(topic);
                connection.start();
                boolean goodByeReceived = false;
                while (!goodByeReceived) {
                    TextMessage textMessage = (TextMessage) messageConsumer
                            .receive();
                    if (textMessage.getText() != null
                            && textMessage.getText().equals("Good bye!")) {
                        goodByeReceived = true;
                    }
                    System.out.println("One:Waiting for messages...");
                    if (textMessage != null) {
                        System.out.print("One:Received the following message: ");
                        System.out.println(textMessage.getText());
                        System.out.println();
                    }
                }
            } catch (Exception ex) {
                Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null,
                        ex);
            } finally {
                try {
                    if (messageConsumer != null) {
                        messageConsumer.close();
                    }
                    if (session != null) {
                        session.close();
                    }
                    if (connection != null) {
                        connection.close();
                    }
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 
SubscriberTwo.java

package in.webtuts.jms.topic;
    import in.webtuts.jms.queue.Producer;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.JMSException;
    import javax.jms.MessageConsumer;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import javax.jms.Topic;
    import javax.naming.InitialContext;
    public class SubscriberTwo {
        /**
         * @param args
         *            the command line arguments
         */
        public static void main(String[] args) {
            ConnectionFactory connectionFactory = null;
            Connection connection = null;
            Session session = null;
            MessageConsumer messageConsumer = null;
            try {
                InitialContext initialContext = new InitialContext();
                connectionFactory = (ConnectionFactory) initialContext
                        .lookup("jms/ConnectionFactory");
                System.out.println("connectionFactory: " + connectionFactory);
                Topic topic = (Topic) initialContext.lookup("jms/Topic");
                System.out.println("Topic: " + topic);
                connection = connectionFactory.createConnection();
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                messageConsumer = session.createConsumer(topic);
                connection.start();
                boolean goodByeReceived = false;
                while (!goodByeReceived) {
                    TextMessage textMessage = (TextMessage) messageConsumer
                            .receive();
                    if (textMessage.getText() != null
                            && textMessage.getText().equals("Good bye!")) {
                        goodByeReceived = true;
                    }
                    System.out.println("Two:Waiting for messages...");
                    if (textMessage != null) {
                        System.out.print("Two:Received the following message: ");
                        System.out.println(textMessage.getText());
                        System.out.println();
                    }
                }
            } catch (Exception ex) {
                Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null,
                        ex);
            } finally {
                try {
                    if (messageConsumer != null) {
                        messageConsumer.close();
                    }
                    if (session != null) {
                        session.close();
                    }
                    if (connection != null) {
                        connection.close();
                    }
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 
AsynchronousSubscriber.java

 package in.webtuts.jms.topic;
    import in.webtuts.jms.queue.Producer;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.JMSException;
    import javax.jms.MessageConsumer;
    import javax.jms.Session;
    import javax.jms.Topic;
    import javax.naming.InitialContext;
    public class AsynchronousSubscriber {
        /**
         * @param args
         *            the command line arguments
         */
        public static void main(String[] args) {
            ConnectionFactory connectionFactory = null;
            Connection connection = null;
            Session session = null;
            MessageConsumer messageConsumer = null;
            try {
                InitialContext initialContext = new InitialContext();
                connectionFactory = (ConnectionFactory) initialContext
                        .lookup("jms/ConnectionFactory");
                System.out.println("connectionFactory: " + connectionFactory);
                Topic topic = (Topic) initialContext.lookup("jms/Topic");
                System.out.println("Topic: " + topic);
                connection = connectionFactory.createConnection();
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                messageConsumer = session.createConsumer(topic);
                messageConsumer.setMessageListener(new TopicMessageListener());
                connection.start();
                Thread.sleep(10000);
            } catch (Exception ex) {
                Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null,
                        ex);
            } finally {
                try {
                    if (messageConsumer != null) {
                        messageConsumer.close();
                    }
                    if (session != null) {
                        session.close();
                    }
                    if (connection != null) {
                        connection.close();
                    }
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

 
TopicMessageListener.java

package in.webtuts.jms.topic;
    import in.webtuts.jms.queue.AsynchronousConsumer;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.MessageListener;
    import javax.jms.TextMessage;
    public class TopicMessageListener implements MessageListener {
        @Override
        public void onMessage(Message message) {
            try {
                TextMessage textMessage = (TextMessage) message;
                System.out.print("Received the following message: ");
                System.out.println(textMessage.getText());
                System.out.println();
            } catch (JMSException ex) {
                Logger.getLogger(AsynchronousConsumer.class.getName()).log(
                        Level.SEVERE, null, ex);
            }
        }
    }

 
Now test the application and see the ouput carefully.
1. run the SubscriberOne.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@bc7c0
    Topic: GlassFish(tm) MQ Destination
    getName():        jmsTopic
    Class:            com.sun.messaging.Topic
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsTopic, imqDestinationDescription=A Description for the Destination Object}

 
From the above output we see that SubscriberOne has not got any message.
2. run the SubscriberTwo.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@1beea90
    Topic: GlassFish(tm) MQ Destination
    getName():        jmsTopic
    Class:            com.sun.messaging.Topic
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsTopic, imqDestinationDescription=A Description for the Destination Object}

 
From the above output we see that SubscriberTwo also has not got any message.
3. run the AsynchronousSubscriber.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@e56328
    Topic: GlassFish(tm) MQ Destination
    getName():        jmsTopic
    Class:            com.sun.messaging.Topic
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsTopic, imqDestinationDescription=A Description for the Destination Object}

 
From the above output we see that AsynchronousSubscriber even has not got any message.
4. run the Publisher.java
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@167198e
    Topic: GlassFish(tm) MQ Destination
    getName():        jmsTopic
    Class:            com.sun.messaging.Topic
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsTopic, imqDestinationDescription=A Description for the Destination Object}
    Sending the following message: Can we meet today ?
    Sending the following message: Do you read me ?
    Sending the following message: Have a good Day!

 
So now publisher has sent three messages to the Topic.
5. look at the SubscriberOne Console
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@bc7c0
    Topic: GlassFish(tm) MQ Destination
    getName():        jmsTopic
    Class:            com.sun.messaging.Topic
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsTopic, imqDestinationDescription=A Description for the Destination Object}
    One:Waiting for messages...
    One:Received the following message: Can we meet today ?
    One:Waiting for messages...
    One:Received the following message: Do you read me ?
    One:Waiting for messages...
    One:Received the following message: Have a good Day!

 
SubscriberOne has got all three messages from the Topic.
6. look at the SubscriberTwo Console
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@1beea90
    Topic: GlassFish(tm) MQ Destination
    getName():        jmsTopic
    Class:            com.sun.messaging.Topic
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsTopic, imqDestinationDescription=A Description for the Destination Object}
    Two:Waiting for messages...
    Two:Received the following message: Can we meet today ?
    Two:Waiting for messages...
    Two:Received the following message: Do you read me ?
    Two:Waiting for messages...
    Two:Received the following message: Have a good Day!

 
SubscriberTwo has got all three messages from the Topic.
7. look at AsynchronousSubscriber Console
Output:

connectionFactory: com.sun.messaging.jms.ra.ConnectionFactoryAdapter@e56328
    Topic: GlassFish(tm) MQ Destination
    getName():        jmsTopic
    Class:            com.sun.messaging.Topic
    getVERSION():        3.0
    isReadonly():        false
    getProperties():    {imqDestinationName=jmsTopic, imqDestinationDescription=A Description for the Destination Object}
    Received the following message: Can we meet today ?
    Received the following message: Do you read me ?
    Received the following message: Have a good Day!

 

We have seen that subscriber has got three messages from the topic. We have onMessage() method in AsynchronousSubscriber class so whenever a message comes to the topic that message is automatically consumed by the subscriber. Also notice that we have Thread.sleep(10000) in AsynchronousSubscriber class so that there is a few delay between connection and message received.

Stopping the GlassFish Server

  •     Open cmd(command) prompt in Windows
  •     Go to directory glassfishv3\glassfish\bin
  •     Execute command – asadmin stop-domain domain1

Once the server gets shutdown you will get output like something below:

Waiting for the domain to stop ........................................
    Command stop-domain executed successfully.

 
Thanks for your reading. Please leave a comment if you have any query.

1 thought on “Configure JMS Client using GlassFish 3

Leave a Reply

Your email address will not be published. Required fields are marked *