# READ messages from a QUEUE using MessageListener

In 
JMS
Published 2022-12-03

This tutorial explains to you how we can read (receive) messages from a queue with Java using a MessageListener. For testing the code I used a WebLogic Application Server.

# JMS queue

In point-to-point messaging system, messages are routed to an individual consumer which maintains a queue of "incoming" messages. This messaging type is built on the concept of message queues, senders, and receivers. Each message is addressed to a specific queue, and the receiving clients extract messages from the queues established to hold their messages. While any number of producers can send messages to the queue, each message is guaranteed to be delivered, and consumed by one consumer. Queues retain all messages sent to them until the messages are consumed or until the messages expire. If no consumers are registered to consume the messages, the queue holds them until a consumer registers to consume them.

# How to receive (read) a message from a WebLogic Queue with Java

In my case I used a WebLogic Queue. Here is a picture showing the Queue with 10 message received and 6 messages that are no read. There are no consumers.

After the Queue Listener is started, you can see that all messages are removed from the queue:

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

On a JSF page (.xhtml) I put a button to receive (read) the message from the WebLogic Queue:

<h:form>
  <p:commandbutton value="tart listener" id="id1" actionlistener="#{receiveMessWithListener.readMessages}">
  </p:commandbutton>
</h:form>

Here is the ReceiveMessWithListener.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 = "receiveMessWithListener")
public class ReceiveMessWithListener  {

  // 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 queue.
  public final static String JNDI_JMS_QUEUE="MyQueue1";

  // Defines the queue. 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(ActionEvent actionEvent)  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);

    QueueConnectionFactory f=(QueueConnectionFactory)ic.lookup(JNDI_JMS_CFACTORY) ;

    QueueConnection con=f.createQueueConnection();
    con.start();

    //2) create queue session  
    QueueSession ses=con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

    //3) get the Queue object  
    Queue t=(Queue)ic.lookup(JNDI_JMS_QUEUE);

    //4) Create QueueReceiver object         
    QueueReceiver receiver=ses.createReceiver(t);

    //5) create listener object  
    MyQueueListener listener=new MyQueueListener();

    //6) register the listener object with receiver  
    receiver.setMessageListener(listener);

    // receiver.setMessageListener(null); --> stop the Listener
  }
}

Here is the MyQueueListener.java file:

package com;
import javax.jms.*;
 
public class MyQueueListener 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 received:"  + msgText );  
              
         } catch(JMSException e)
               {System.out.println(e);
         }
    }
}

When we want to stop the listener, we have to run the following command:

 receiver.setMessageListener(null);

Messages can be consumed in either of 2 ways:

  • 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. That means the messages are read in the order they arrive in the queue (there is only one thread).

  • 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. That means the messages are read in the order they arrive in the queue, but there is one thread for each read (2 messages can be read in the same time).