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 Type Body Contains
TextMessage A java.lang.String object (for example, the contents of an Extensible Markup Language file).
MapMessage A 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.
BytesMessage A stream of uninterpreted bytes. This message type is for literally encoding a body to match an existing message format.
StreamMessage A stream of primitive values in the Java programming language, filled and read sequentially.
ObjectMessage A Serializable object in the Java programming language.
Message Nothing. 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

 

Topic connection factory

 

Queue or Topic connection factory

 

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

 

The following line of code performs a JNDI API lookup of the 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

 

Topic connection

 

Queue or Topic connection

 

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

 

Close topic connection

 

Close queue or topic connection

 

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:

 

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:

 

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

 

or

 

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:

 

 

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

 

With a TopicPublisher, we use the publish method:

 

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

For a queue

 

For a topic

 

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:

 

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:

 

 

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:

 

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:

 

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

 

Consumer.java

 

AsynchronousConsumer.java

 

QueueMessageListener.java

 

MessageQueueBrowser.java

 

Now test the application and see the ouput carefully at each run.

1. run the MessageQueueBrowser.java

Output:

 

From the above output we see that there is no message in the queue initially.

2. run the Producer.java

Output:

 

So above output says that three messages have been sent to the queue.

3. run the MessageQueueBrowser.java

Output:

 

So above output says that three messages available in the queue.

4. run the Consumer.java

Output:

 

So we have got three messages from the queue.

5. run the MessageQueueBrowser.java

Output:

 

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:

 

Again producer has sent three messages to the queue.

7. run the MessageQueueBrowser.java

Output:

 

So above output says that three messages available in the queue.

8. run the AsynchronousConsumer.java

Output:

 

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:

 

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

 

SubscriberOne.java

 

SubscriberTwo.java

 

AsynchronousSubscriber.java

 

TopicMessageListener.java

 

Now test the application and see the ouput carefully.

1. run the SubscriberOne.java

Output:

 

From the above output we see that SubscriberOne has not got any message.

2. run the SubscriberTwo.java

Output:

 

From the above output we see that SubscriberTwo also has not got any message.

3. run the AsynchronousSubscriber.java

Output:

 

From the above output we see that AsynchronousSubscriber even has not got any message.

4. run the Publisher.java

Output:

 

So now publisher has sent three messages to the Topic.

5. look at the SubscriberOne Console

Output:

 

SubscriberOne has got all three messages from the Topic.

6. look at the SubscriberTwo Console

Output:

 

SubscriberTwo has got all three messages from the Topic.

7. look at AsynchronousSubscriber Console

Output:

 

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:

 

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

Soumitra

Software Professional, I am passionate to work on web/enterprise application. For more information please go to about me. You can follow on Twitter. You can be a friend on Facebook or Google Plus or Linkedin

Leave a Reply

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

Time limit is exhausted. Please reload CAPTCHA.