The Java EE 5 Tutorial

A Simple Example of Asynchronous Message Consumption

This section describes the receiving programs in an example that uses a message listener to consume messages asynchronously. This section then explains how to compile and run the programs using the Application Server.

The following sections describe the steps in creating and running the example:

Writing the Client Programs for the Asynchronous Receive Example

The sending program is producer/src/java/Producer.java, the same program used in the example in A Simple Example of Synchronous Message Receives.

An asynchronous consumer normally runs indefinitely. This one runs until the user types the letter q or Q to stop the program.

    The receiving program, asynchconsumer/src/java/AsynchConsumer.java, performs the following steps:

  1. Injects resources for a connection factory, queue, and topic.

  2. Assigns either the queue or topic to a destination object, based on the specified destination type.

  3. Creates a Connection and a Session.

  4. Creates a MessageConsumer.

  5. Creates an instance of the TextListener class and registers it as the message listener for the MessageConsumer:

    listener = new TextListener();consumer.setMessageListener(listener);
  6. Starts the connection, causing message delivery to begin.

  7. Listens for the messages published to the destination, stopping when the user types the character q or Q:

    System.out.println("To end program, type Q or q, " + "then <return>");
    inputStreamReader = new InputStreamReader(System.in);
    while (!((answer == ’q’) || (answer == ’Q’))) { 
        try { 
            answer = (char) inputStreamReader.read(); 
        } catch (IOException e) { 
            System.out.println("I/O exception: " + e.toString()); 
        }
    }
  8. Closes the connection, which automatically closes the session and MessageConsumer.

    The message listener, asynchconsumer/src/java/TextListener.java, follows these steps:

  1. When a message arrives, the onMessage method is called automatically.

  2. The onMessage method converts the incoming message to a TextMessage and displays its content. If the message is not a text message, it reports this fact:

    public void onMessage(Message message) { 
        TextMessage msg = null; 
        try { 
            if (message instanceof TextMessage) { 
                msg = (TextMessage) message; 
                 System.out.println("Reading message: " + msg.getText()); 
            } else { 
                 System.out.println("Message is not a " + "TextMessage"); 
            } 
        } catch (JMSException e) { 
            System.out.println("JMSException in onMessage(): " + e.toString()); 
        } catch (Throwable t) { 
            System.out.println("Exception in onMessage():" + t.getMessage()); 
        }
    }

You will use the connection factory and destinations you created in Creating JMS Administered Objects for the Synchronous Receive Example.

Compiling and Packaging the AsynchConsumer Client

    To compile and package the AsynchConsumer example using NetBeans IDE, follow these steps:

  1. In NetBeans IDE, choose Open Project from the File menu.

  2. In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jms/simple/.

  3. Select the asynchconsumer folder.

  4. Select the Open as Main Project check box.

  5. Click Open Project.

  6. Right-click the project and choose Build.

    To compile and package the AsynchConsumer example using Ant, follow these steps:

  1. In a terminal window, go to the asynchconsumer directory:


    cd ../../asynchconsumer
    
  2. Type the following command:


    ant
    

The targets package both the main class and the message listener class in the JAR file and place the file in the dist directory for the example.

Running the Clients for the Asynchronous Receive Example

    To run the programs using NetBeans IDE, follow these steps.

  1. Run the AsynchConsumer example:

    1. Right-click the asynchconsumer project and choose Properties.

    2. Select Run from the Categories tree.

    3. In the Arguments field, type the following:


      topic
      
    4. Click OK.

    5. Right-click the project and choose Run.

      The program displays the following lines and appears to hang:


      Destination type is topic
      To end program, type Q or q, then <return>
  2. Now run the Producer example:

    1. Right-click the producer project and choose Properties.

    2. Select Run from the Categories tree.

    3. In the Arguments field, type the following:


      topic 3
      
    4. Click OK.

    5. Right-click the project and choose Run.

      The output of the program looks like this:


      Destination type is topic
      Sending message: This is message 1
      Sending message: This is message 2
      Sending message: This is message 3

      In the other window, the AsynchConsumer program displays the following:


      Destination type is topic
      To end program, type Q or q, then <return>
      Reading message: This is message 1
      Reading message: This is message 2
      Reading message: This is message 3
      Message is not a TextMessage

      The last line appears because the program has received the non-text control message sent by the Producer program.

  3. Type Q or q in the Output window and press Return to stop the program.

  4. Now run the programs using a queue. In this case, as with the synchronous example, you can run the Producer program first, because there is no timing dependency between the sender and receiver.

    1. Right-click the producer project and choose Properties.

    2. Select Run from the Categories tree.

    3. In the Arguments field, type the following:


      queue 3
      
    4. Click OK.

    5. Right-click the project and choose Run.

      The output of the program looks like this:


      Destination type is queue
      Sending message: This is message 1
      Sending message: This is message 2
      Sending message: This is message 3
  5. Run the AsynchConsumer program.

    1. Right-click the asynchconsumer project and choose Properties.

    2. Select Run from the Categories tree.

    3. In the Arguments field, type the following:


      queue
      
    4. Click OK.

    5. Right-click the project and choose Run.

      The output of the program looks like this:


      Destination type is queue
      To end program, type Q or q, then <return>
      Reading message: This is message 1
      Reading message: This is message 2
      Reading message: This is message 3
      Message is not a TextMessage
  6. Type Q or q in the Output window and press Return to stop the program.

    To run the clients using the appclient command, follow these steps:

  1. Run the AsynchConsumer program, specifying the topic destination type.


    cd dist
    appclient -client asynchconsumer.jar topic
    

    The program displays the following lines and appears to hang:


    Destination type is topic
    To end program, type Q or q, then <return>
  2. In the terminal window where you ran the Producer program previously, run the program again, sending three messages. The command looks like this:


    appclient -client producer.jar topic 3
    

    The output of the program looks like this:


    Destination type is topic
    Sending message: This is message 1
    Sending message: This is message 2
    Sending message: This is message 3

    In the other window, the AsynchConsumer program displays the following:


    Destination type is topic
    To end program, type Q or q, then <return>
    Reading message: This is message 1
    Reading message: This is message 2
    Reading message: This is message 3
    Message is not a TextMessage

    The last line appears because the program has received the non-text control message sent by the Producer program.

  3. Type Q or q and press Return to stop the program.

  4. Now run the programs using a queue. In this case, as with the synchronous example, you can run the Producer program first, because there is no timing dependency between the sender and receiver:


    appclient -client producer.jar queue 3
    

    The output of the program looks like this:


    Destination type is queue
    Sending message: This is message 1
    Sending message: This is message 2
    Sending message: This is message 3
  5. Run the AsynchConsumer program:


    appclient -client asynchconsumer.jar queue
    

    The output of the program looks like this:


    Destination type is queue
    To end program, type Q or q, then <return>
    Reading message: This is message 1
    Reading message: This is message 2
    Reading message: This is message 3
    Message is not a TextMessage
  6. Type Q or q to stop the program.