JMS Publish/Subscribe Message Example

In JMS tutorial, you read about JMS messaging domains Point to Point Domain and Publish Subscribe Domain. In this example, we will go through one such example of Publish/Subscribe messaging domain. The publish/subscribe messaging domain is a one-to-many model where one publisher sends the message through a topic to all the subscribers who are active and they receive the message through topic.

Publish Subscribe JMS Messaging
Publish Subscribe JMS Messaging

Publish/Subscribe Messaging Publisher Application Flow

A typical publish/subscribe messaging example for the sender application is given below. The following steps for the application are –

  1. Firstly, we will obtain the Initial Context object for the JMS server.
  2. After that use the initial context object for lookup a topic object.
  3. Again we will use the initial context object for lookup the topic connection factory.
  4. Then use the topic connection factory to create the topic connection as it represents the physical connection of the JMS server.
  5. After creating the topic connection factory we will create the topic session where the first parameter will decide whether the session is transacted or not. But we will use a non-transacted session and the second parameter decides the delivery mode.
  6. After this we will create a topic publisher for topic object and then create a message.
  7. Then send the message such as “Hello” to the topic object.
  8. After that close the topic connection as you close the topic connection it will automatically close the session and topic publisher.

Let’s look at example below:

package pubSub;     

import javax.naming.InitialContext;                                                                           
import javax.jms.Topic;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.TopicPublisher;
import javax.jms.DeliveryMode;
import javax.jms.TopicSession;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
                                                                           
public class Publisher
{
    public static void main(String[] args) throws Exception
    {
       // get the initial context
       InitialContext ctx = new InitialContext();
                                                                          
       // lookup the topic object
       Topic topic = (Topic) ctx.lookup("topic/topic0");
                                                                          
       // lookup the topic connection factory
       TopicConnectionFactory connFactory = (TopicConnectionFactory) ctx.
           lookup("topic/connectionFactory");
                                                                          
       // create a topic connection
       TopicConnection topicConn = connFactory.createTopicConnection();
                                                                          
       // create a topic session
       TopicSession topicSession = topicConn.createTopicSession(false, 
           Session.AUTO_ACKNOWLEDGE);
                                                                          
       // create a topic publisher
       TopicPublisher topicPublisher = topicSession.createPublisher(topic);
       topicPublisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
                                                                          
       // create the "Hello World" message
       TextMessage message = topicSession.createTextMessage();
       message.setText("Hello World");
                                                                          
       // publish the messages
       topicPublisher.publish(message);
                                                                          
       // print what we did
       System.out.println("Message published: " + message.getText());
                                                                          
       // close the topic connection
       topicConn.close();
    }
}

Publish/Subscribe Messaging Subscriber Application Flow

Most of the steps for the receiver side are same as for the sender application – except it will listen the message rather than sending the JMS message.

package pubSub;      

import javax.naming.InitialContext;                                                                           
import javax.jms.Topic;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
                                                                           
public class Subscriber
{
    public static void main(String[] args) throws Exception
    {
       // get the initial context
       InitialContext ctx = new InitialContext();
                                                                          
       // lookup the topic object
       Topic topic = (Topic) ctx.lookup("topic/topic0");
                                                                          
       // lookup the topic connection factory
       TopicConnectionFactory connFactory = (TopicConnectionFactory) ctx.
           lookup("topic/connectionFactory");
                                                                          
       // create a topic connection
       TopicConnection topicConn = connFactory.createTopicConnection();
                                                                          
       // create a topic session
       TopicSession topicSession = topicConn.createTopicSession(false,
           Session.AUTO_ACKNOWLEDGE);
                                                                          
       // create a topic subscriber
       TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic);
                                                                          
       // start the connection
       topicConn.start();
                                                                          
       // receive the message
       TextMessage message = (TextMessage) topicSubscriber.receive();
                                                                          
       // print the message
       System.out.println("Message received: " + message.getText());
                                                                          
       // close the topic connection
       topicConn.close();
    }
}

In the above code the receiver will receive the message from the sender and print it i.e. Hello World.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

5 thoughts on “JMS Publish/Subscribe Message Example”

  1. suppose I have three client as Receiver clientA, clientB, clientC and so on. clientA is down for 2 hour, once clientA up how should we have guaranty that clientA we receive all messages from last two hour(which was missed in downtime) .

    Reply
  2. Make sure you have set the initial context correctly based on your environment.

    // Obtain a JNDI connection
    Properties env = new Properties();
    env.put(Context.INITIAL_CONTEXT_FACTORY,
    “weblogic.jndi.WLInitialContextFactory”);
    env.put(Context.PROVIDER_URL, “t3://server-name:server-port”);
    env.put(Context.SECURITY_PRINCIPAL, “weblogic”);
    env.put(Context.SECURITY_CREDENTIALS, “weblogic”);

    InitialContext ctx = new InitialContext(env);

    Reply
    • Hi Ashish
      I have updated my source code but get some issues

      Exception in thread “main” javax.naming.NoInitialContextException: Cannot instantiate class: weblogic.jndi.WLInitialContextFactory [Root exception is java.lang.ClassNotFoundException: weblogic.jndi.WLInitialContextFactory]
      at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
      at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
      at javax.naming.InitialContext.init(Unknown Source)
      at javax.naming.InitialContext.(Unknown Source)
      at com.cme.JMS.Sender.main(Sender.java:27)
      Caused by: java.lang.ClassNotFoundException: weblogic.jndi.WLInitialContextFactory
      at java.net.URLClassLoader$1.run(Unknown Source)
      at java.net.URLClassLoader$1.run(Unknown Source)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.net.URLClassLoader.findClass(Unknown Source)
      at java.lang.ClassLoader.loadClass(Unknown Source)
      at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
      at java.lang.ClassLoader.loadClass(Unknown Source)
      at java.lang.Class.forName0(Native Method)
      at java.lang.Class.forName(Unknown Source)
      at com.sun.naming.internal.VersionHelper12.loadClass(Unknown Source)
      at com.sun.naming.internal.VersionHelper12.loadClass(Unknown Source)
      … 5 more

      Can you help to check this?

      Many Thanks,
      Phung

      Reply
  3. Exception in thread “main” javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
    at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
    at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(Unknown Source)
    at javax.naming.InitialContext.lookup(Unknown Source)
    at test.jms.Publisher.main(Publisher.java:20)

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.