# Subscribe to a Topic using MessageListener (II)

In 
JMS
Published 2022-12-03

This tutorial explains to you how we can read messages from a topic with Java using a MessageListener. For testing the code I used a WebLogic Application Server. The code I created in Java connects to the WebLogic Topic and listen/ read 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 a non-durable subscriber written in Java.

In my case I used a WebLogic Topic. Here is a picture showing the Topic with 1 message received and 1 Consumers waiting for messages (the Durable Subscriber).

A new message arrive to the topic, but the Durable Subscriber is not listening to the topic:

After the Topic Listener is started, you can see that 2 Consumer are waiting for messages (the Durable Subscriber is sleeping/ not listening):

When a message is received you will see that:

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 subscribe (read) the message from the WebLogic Topic:

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

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="ConnectionFactory2";

  // 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.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.createSubscriber(t);

    //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);
         }
    }
}