# READ message from DURABLE Topic

In 
JMS
Published 2022-12-03

This tutorial explains to you how we can read messages from a WebLogic topic with Java using a MessageListener using a durable subscription (for testing the code I used a 12c WebLogic Application Server).

The Java code I created connects to the WebLogic Topic and listen for incoming messages. This code acts as a Topic Subscriber. This behaviour is when we have a Durable Subscriber defined on the Topic and you are connected to the Topic using that durable subscriber written in Java.

# WebLogic Topic Subscription Identifiers

In JMS, a subscription is identified and located based on :

  1. the topic with which it is associated;

  2. the connection Client ID string that is specified for the connection that is used to access the subscription

  3. if using durable subscriptions, the subscription name that is specified when the durable subscription is created.

  4. Client ID Policy option. If two WebLogic JMS subscription references on the same physical topic have the same Client ID and subscription name, then the references resolve to a single subscription if the Client ID Policy is also the same, but they resolve to two different subscriptions if the Client ID Policies are different.

# Create a durable subscription to WebLogic Topic with Java

In my case I used a WebLogic Topic. Here is a picture showing the Topic with 0 message received and 1 "Consumer Current" (the Durable Subscriber created in WebLogic for the topic).

2 messages arrive to the topic, but the Durable Subscriber is not listening to the topic, we have 2 "Messages Current":

After the Topic Listener is started, you can see that there are no "Messages Current" because all the Durable Subscribers (one in this case) have read the received messages.

For testing, I used the following: Eclipse, JDK 8, a WebLogic Server 12c and I created a Web application using JSF (PrimeFaces).

On a JSF page (.xhtml) I put a button to create a subscription to WebLogic Topic:

<html>
 <body>
   <h:form>
      <p:commandbutton value="Start Subscriber Listener" actionlistener="#{subscriberListener.readMessages}">
      </p:commandbutton>
   </h:form>
 </body>
</html>

Here is the SubscriberListener.java file :

package com;

import java.util.Hashtable;

//import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
//import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import javax.naming.*;  
import javax.jms.*;

@ManagedBean (name = "subscriberListener")
public class SubscriberListener {

// Defines the JNDI context factory.
public final static String JNDI_CFACTORY="weblogic.jndi.WLInitialContextFactory";

// Defines the JMS context factory.
public final static String JNDI_JMS_CFACTORY="ConnectionFactory1";

// Defines the topic.
public final static String JNDI_JMS_TOPIC="jndi/Topic1";

//The port is for the Managed Server
// or Admin Server where the JMS Server is running.
public final static String WebLogicURL="t3://pc:7004";

public void readMessages()  throws Exception {

    //1)Create and start connection 
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_CFACTORY);
    env.put(Context.PROVIDER_URL, WebLogicURL);
     
    InitialContext ic=new InitialContext(env);   
     
    TopicConnectionFactory f=(TopicConnectionFactory)ic.lookup(JNDI_JMS_CFACTORY) ;   
     
    TopicConnection con=f.createTopicConnection();  
     
   // con.setClientID("100");
    con.start();  
     
    //2) create topic session  
    TopicSession ses=con.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);  
     
    //3) get the Queue object  
    Topic t=(Topic)ic.lookup(JNDI_JMS_TOPIC);  
     
    //4) Create TopicSubscriber object         
    TopicSubscriber subscriber=ses.createDurableSubscriber(t, "ABC_Reader");
     
    //5) create listener object  
    MyTopicListener listener=new MyTopicListener();  
       
    //6) register the listener object with receiver  
    subscriber.setMessageListener(listener); 
     
    //subscriber.setMessageListener(null); --> stop the Listener
    }
}

Here is the MyTopicListener.java file:

package com;
import javax.jms.*;

public class MyTopicListener implements MessageListener {

    @Override
    public void onMessage(Message msg) {
         
         try{   
             String msgText;
              
             if (msg instanceof TextMessage) {
               msgText = ((TextMessage)msg).getText();
             } else {
               msgText = msg.toString();
             }
                 
             System.out.println("The following message was read by a subscriber:"  + msgText );  
              
         } catch(JMSException e)
               {System.out.println(e);
         }
    }
}