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 Messaging Publisher Application Flow
A typical publish/subscribe messaging example for the sender application is given below. The following steps for the application are –
- Firstly, we will obtain the Initial Context object for the JMS server.
- After that use the initial context object for lookup a topic object.
- Again we will use the initial context object for lookup the topic connection factory.
- Then use the topic connection factory to create the topic connection as it represents the physical connection of the JMS server.
- 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.
- After this we will create a topic publisher for topic object and then create a message.
- Then send the message such as “Hello” to the topic object.
- 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 !!
Shambhu
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) .
Lokesh Gupta
If messages are persistent, its guaranteed.
Ashish Jayee
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);
Phung
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
Siddharth
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)