JMS QueueRequestor Example

This example shows you how to use a QueueRequestor with ActiveMQ.

JMS is mainly used to send messages asynchronously so that the producer of a message is not waiting for the result of the message consumption. However, there are cases where it is necessary to have a synchronous behavior: the code sending a message requires a reply for this message before continuing its execution.
A QueueRequestor facilitates this use case by providing a simple request/reply abstraction on top of JMS.

The example consists in two classes:

TextReverserService
A JMS MessageListener which consumes text messages and sends replies containing the reversed text
QueueRequestorExample
A JMS Client which uses a QueueRequestor to send text requests to a queue and receive replies with the reversed text in a synchronous fashion

Example step-by-step

To run the example, simply type mvn verify -Pexample from this directory

  1. First we need to get an initial context so we can look-up the JMS connection factory from JNDI. This initial context will get it's properties from the client-jndi.properties file in the directory ../common/config
  2.            InitialContext initialContext = getContext();
            
  3. We look up the JMS queue from JNDI
  4.            Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue");
            
  5. We look up JMS queue connection factory from JNDI
  6.            QueueConnectionFactory cf = (QueueConnectionFactory)initialContext.lookup("/ConnectionFactory");
            
  7. We create the TextReverserService which will consume messages from the queue
  8.             TextReverserService reverserService = new TextReverserService(cf, queue);
            
  9. We Create a JMS queue connection
  10.            connection = cf.createQueueConnection();
            
  11. We start the connection. In order for delivery to occur on any consumers or subscribers on a connection, the connection must be started
  12.            connection.start();
            
  13. We create a JMS queue session. The session is created as non transacted and will auto acknowledge messages (this is mandatory to use it to create a QueueRequestor)
  14.            QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            
  15. We create a JMS QueueRequestor using the session and the queue
  16.            QueueRequestor queueRequestor = new QueueRequestor(session, queue);
            
  17. We create a JMS text message to send as a request
  18.            TextMessage request = session.createTextMessage("Hello, World!");
            
  19. We use the queue requestor to send the request and block until a reply is received.
    Using the queue requestor simplify request/reply use case by abstracting boilerplate JMS code (creating a temporary queue, a consumer and a producer, setting the JMS ReplyTo header on the request, sending the request with the producer, consuming the message from the consumer). All this code is replaced by a single call to QueueRequestor.request() method.

  20.            TextMessage reply = (TextMessage)queueRequestor.request(request);
            
  21. The reply's text contains the reverse of the request's text
  22.            System.out.println("Send request: " + request.getText());
               System.out.println("Received reply:" + reply.getText());
            
  23. We close the queue requestor to release all the JMS resources it created to provide request/reply mechanism
  24.            queueRequestor.close()
            
  25. We do the same for the text reverser service
  26.            reverserService.close()
            
  27. And finally, always remember to close your JMS connections and resources after use, in a finally block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects
  28.            finally
               {
                  if (initialContext != null)
                  {
                    initialContext.close();
                  }
                  if (connection != null)
                  {
                     connection.close();
                  }
               }