JavaTM Message Service Tutorial
Tutorial Homepage | TOC | Prev | Next | Index

4    Writing Simple JMS Client Applications

This chapter shows how to create and to run simple JMS client programs. A J2EETM application client commonly accesses J2EE components installed in a server based on J2EE technology ("J2EE server"). The clients in this chapter, however, are simple standalone programs that run outside the server as class files. The clients demonstrate the basic tasks that a JMS application must perform:

In a J2EE application, some of these tasks are performed, in whole or in part, by the EJBTM container. If you learn about these tasks, you will have a good basis for understanding how a JMS application works on the J2EE platform.

The chapter covers the following topics:

Each example consists of two programs: one that sends messages and one that receives them. You can run the programs in two terminal windows.

When you write a JMS application to run in a J2EE component, you use many of the same methods in much the same sequence as you do for a JMS client program. However, there are some significant differences. Chapter 6 describes these differences, and the following chapters provide examples that illustrate them.

4.1   Setting Your Environment for Running Applications

Before you can run the examples, you need to make sure that your environment is set appropriately. Table 4.1 shows how to set the environment variables needed to run J2EE applications on Microsoft Windows and UNIX® platforms.

Table 4.1:    Environment Settings for Compiling and Running
J2EE Applications
Platform
Variable Name
Values
Microsoft Windows
%JAVA_HOME%
Directory in which the JavaTM 2 SDK, Standard Edition, version 1.3.1, is installed
%J2EE_HOME%
Directory in which the J2EE SDK 1.3.1 is installed, usually C:\j2sdkee1.3.1
%CLASSPATH%
Include the following:
.;%J2EE_HOME%\lib\j2ee.jar;
%J2EE_HOME%\lib\locale
%PATH%
Include %J2EE_HOME%\bin
UNIX
$JAVA_HOME
Directory in which the Java 2 SDK, Standard Edition, version 1.3.1, is installed
$J2EE_HOME
Directory in which the J2EE SDK 1.3.1 is installed, usually $HOME/j2sdkee1.3.1
$CLASSPATH
Include the following:
.:$J2EE_HOME/lib/j2ee.jar:
$J2EE_HOME/lib/locale
$PATH
Include $J2EE_HOME/bin

The appendix provides more examples of client programs that demonstrate additional features of the JMS API. You can download still more examples of JMS client programs from the JMS API Web site, http://java.sun.com/products/jms/. If you downloaded the tutorial examples as described in the preface, you will find the examples for this chapter in the directory jms_tutorial/examples/simple (on UNIX systems) or jms_tutorial\examples\simple (on Microsoft Windows systems).

4.2   A Simple Point-to-Point Example

This section describes the sending and receiving programs in a PTP example that uses the receive method to consume messages synchronously. This section then explains how to compile and run the programs, using the J2EE SDK 1.3.1.

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

4.2.1   Writing the PTP Client Programs

The sending program, SimpleQueueSender.java, performs the following steps:

  1. Performs a Java Naming and Directory InterfaceTM (JNDI) API lookup of the QueueConnectionFactory and queue
  2. Creates a connection and a session
  3. Creates a QueueSender
  4. Creates a TextMessage
  5. Sends one or more messages to the queue
  6. Sends a control message to indicate the end of the message stream
  7. Closes the connection in a finally block, automatically closing the session and QueueSender

The receiving program, SimpleQueueReceiver.java, performs the following steps:

  1. Performs a JNDI API lookup of the QueueConnectionFactory and queue
  2. Creates a connection and a session
  3. Creates a QueueReceiver
  4. Starts the connection, causing message delivery to begin
  5. Receives the messages sent to the queue until the end-of-message-stream control message is received
  6. Closes the connection in a finally block, automatically closing the session and QueueReceiver

The receive method can be used in several ways to perform a synchronous receive. If you specify no arguments or an argument of 0, the method blocks indefinitely until a message arrives:

Message m = queueReceiver.receive();

Message m = queueReceiver.receive(0);

For a simple client program, this may not matter. But if you do not want your program to consume system resources unnecessarily, use a timed synchronous receive. Do one of the following:

The SimpleQueueReceiver program uses an indefinite while loop to receive messages, calling receive with a timeout argument. Calling receiveNoWait would have the same effect.

4.2.2   Compiling the PTP Clients

To compile the PTP example, do the following.

  1. Make sure that you have set the environment variables shown in Table 4.1.
  2. At a command line prompt, compile the two source files:
    javac SimpleQueueSender.java
    javac SimpleQueueReceiver.java
    

4.2.3   Starting the JMS Provider

When you use the J2EE SDK 1.3.1, your JMS provider is the SDK. At another command line prompt, start the J2EE server as follows:

j2ee -verbose

Wait until the server displays the message "J2EE server startup complete."

4.2.4   Creating the JMS Administered Objects

In the window in which you compiled the clients, use the j2eeadmin command to create a queue named MyQueue. The last argument tells the command what kind of destination to create.

j2eeadmin -addJmsDestination MyQueue queue

To make sure that the queue has been created, use the following command:

j2eeadmin -listJmsDestination

This example uses the default QueueConnectionFactory object supplied with the J2EE SDK 1.3.1. With a different J2EE product, you might need to create a connection factory yourself.

4.2.5   Running the PTP Clients

Run the clients as follows.

  1. Run the SimpleQueueSender program, sending three messages. You need to define a value for jms.properties.

    • On a Microsoft Windows system, type the following command:
      java -Djms.properties=%J2EE_HOME%\config\jms_client.properties SimpleQueueSender MyQueue 3
      
    • On a UNIX system, type the following command:
      java -Djms.properties=$J2EE_HOME/config/jms_client.properties SimpleQueueSender MyQueue 3
      

    The output of the program looks like this:

    Queue name is MyQueue
    Sending message: This is message 1
    Sending message: This is message 2
    Sending message: This is message 3
    
  2. In the same window, run the SimpleQueueReceiver program, specifying the queue name. The java commands look like this:

    • Microsoft Windows systems:
      java -Djms.properties=%J2EE_HOME%\config\jms_client.properties SimpleQueueReceiver MyQueue
      
    • UNIX systems:
      java -Djms.properties=$J2EE_HOME/config/jms_client.properties SimpleQueueReceiver MyQueue
      

    The output of the program looks like this:

    Queue name is MyQueue
    Reading message: This is message 1
    Reading message: This is message 2
    Reading message: This is message 3
    
  3. Now try running the programs in the opposite order. Start the SimpleQueueReceiver program. It displays the queue name and then appears to hang, waiting for messages.

  4. In a different terminal window, run the SimpleQueueSender program. When the messages have been sent, the SimpleQueueReceiver program receives them and exits.

4.2.6   Deleting the Queue

You can delete the queue you created as follows:

j2eeadmin -removeJmsDestination MyQueue

You will use it again in Section 4.4.1, "Communicating Between Two J2EE Servers," however.

4.3   A Simple Publish/Subscribe Example

This section describes the publishing and subscribing programs in a pub/sub example that uses a message listener to consume messages asynchronously. This section then explains how to compile and run the programs, using the J2EE SDK 1.3.1.

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

4.3.1   Writing the Pub/Sub Client Programs

The publishing program, SimpleTopicPublisher.java, performs the following steps:

  1. Performs a JNDI API lookup of the TopicConnectionFactory and topic
  2. Creates a connection and a session
  3. Creates a TopicPublisher
  4. Creates a TextMessage
  5. Publishes one or more messages to the topic
  6. Closes the connection, which automatically closes the session and TopicPublisher

The receiving program, SimpleTopicSubscriber.java, performs the following steps:

  1. Performs a JNDI API lookup of the TopicConnectionFactory and topic
  2. Creates a connection and a session
  3. Creates a TopicSubscriber
  4. Creates an instance of the TextListener class and registers it as the message listener for the TopicSubscriber
  5. Starts the connection, causing message delivery to begin
  6. Listens for the messages published to the topic, stopping when the user enters the character q or Q
  7. Closes the connection, which automatically closes the session and TopicSubscriber

The message listener, 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.

4.3.2   Compiling the Pub/Sub Clients

To compile the pub/sub example, do the following.

  1. Make sure that you have set the environment variables shown in Table 4.1.
  2. Compile the programs and the message listener class:
    javac SimpleTopicPublisher.java
    javac SimpleTopicSubscriber.java
    javac TextListener.java
    

4.3.3   Starting the JMS Provider

If you did not do so before, start the J2EE server in another terminal window:

j2ee -verbose

Wait until the server displays the message "J2EE server startup complete."

4.3.4   Creating the JMS Administered Objects

In the window in which you compiled the clients, use the j2eeadmin command to create a topic named MyTopic. The last argument tells the command what kind of destination to create.

j2eeadmin -addJmsDestination MyTopic topic

To verify that the queue has been created, use the following command:

j2eeadmin -listJmsDestination

This example uses the default TopicConnectionFactory object supplied with the J2EE SDK 1.3.1. With a different J2EE product, you might need to create a connection factory.

4.3.5   Running the Pub/Sub Clients

Run the clients as follows.

  1. Run the SimpleTopicSubscriber program, specifying the topic name. You need to define a value for jms.properties.

    • On a Microsoft Windows system, type the following command:
      java -Djms.properties=%J2EE_HOME%\config\jms_client.properties SimpleTopicSubscriber MyTopic
      
    • On a UNIX system, type the following command:
      java -Djms.properties=$J2EE_HOME/config/jms_client.properties SimpleTopicSubscriber MyTopic
      

    The program displays the following lines and appears to hang:

    Topic name is MyTopic
    To end program, enter Q or q, then <return>
    
  2. In another terminal window, run the SimpleTopicPublisher program, publishing three messages. The java commands look like this:

    • Microsoft Windows systems:
      java -Djms.properties=%J2EE_HOME%\config\jms_client.properties SimpleTopicPublisher MyTopic 3
      
    • UNIX systems:
      java -Djms.properties=$J2EE_HOME/config/jms_client.properties SimpleTopicPublisher MyTopic 3
      

    The output of the program looks like this:

    Topic name is MyTopic
    Publishing message: This is message 1
    Publishing message: This is message 2
    Publishing message: This is message 3
    

    In the other window, the program displays the following:

    Reading message: This is message 1
    Reading message: This is message 2
    Reading message: This is message 3
    

    Enter Q or q to stop the program.

4.3.6   Deleting the Topic and Stopping the Server

  1. You can delete the topic you created as follows:
    j2eeadmin -removeJmsDestination MyTopic
    

    You will use it again in Section 4.4.2, "Communicating Between a J2EE Server and a System Not Running a J2EE Server," however.

  2. If you wish, you can stop the J2EE server as well:
    j2ee -stop
    

4.4   Running JMS Client Programs on Multiple Systems

JMS client programs can communicate with each other when they are running on different systems in a network. The systems must be visible to each other by name--the UNIX host name or the Microsoft Windows computer name--and must both be running the J2EE server.

This section explains how to produce and to consume messages in two different situations:

4.4.1   Communicating Between Two J2EE Servers

Suppose that you want to run the SimpleQueueSender program on one system, mars, and the SimpleQueueReceiver program on another system, earth. To do so, follow these steps.

  1. Start the J2EE server on both systems. Enter the following command in a terminal window on each system:
    j2ee -verbose
    
  2. On earth, create a QueueConnectionFactory object, using a command like the following:
    j2eeadmin -addJmsFactory jms/EarthQCF queue
    
  3. On mars, create a connection factory with the same name that points to the server on earth. Enter, on one line, a command like the following:
    j2eeadmin -addJmsFactory jms/EarthQCF queue -props url=corbaname:iiop:earth:1050#earth
    

    You can modify the script setup.bat or setup.sh, which you will use in Chapter 10, to automate this command.

  4. In each source program, change the line that looks up the connection factory so that it refers to the new connection factory:
    queueConnectionFactory = 
        (QueueConnectionFactory) jndiContext.lookup("jms/EarthQCF");
    
  5. Recompile the programs; then run them by using the instructions in Section 4.2.5, "Running the PTP Clients." Because both connection factories have the same name, you can run either the sender or the receiver on either system. (Note: A bug in the JMS provider in the J2EE SDK may cause a runtime failure to create a connection to systems that use the Dynamic Host Configuration Protocol [DHCP] to obtain an IP address.)

You can run the pub/sub example in the same way by creating a TopicConnectionFactory object on both systems. For an example showing how to deploy J2EE applications on two different systems, see Chapter 10.

4.4.2   Communicating Between a J2EE Server and a System Not Running a J2EE Server

In order for two standalone client programs to communicate, both must have the J2EE SDK installed locally. However, the J2EE server does not have to be running on both systems. Suppose that you want to run the SimpleTopicPublisher and the SimpleTopicSubscriber programs on two systems called earth and mars, as in Section 4.4.1, but that the J2EE server will be running only on earth. To specify the system running the server, you can either

When the server is running only on the remote system, you do not have to create a connection factory on the local system that refers to the remote system.

The procedure for using the command line is as follows:

  1. Start the J2EE server on earth:
    j2ee -verbose
    
  2. Set the J2EE_HOME environment variable and the classpath on mars so that they point to the J2EE SDK 1.3.1 installation on mars (see Table 4.1).
  3. To access a client program on a system running the server from a client program on a system not running the server, use the following option, where hostname is the name of the system running the J2EE server:
    -Dorg.omg.CORBA.ORBInitialHost=hostname
    
  4. This option allows you to access the naming service on the remote system. For example, if the server is running on earth, use a command like the following to run the SimpleTopicSubscriber program on mars. Make sure that the destination you specify exists on the server running on earth.

If all the remote programs you need to access are on the same system, you can edit the file %J2EE_HOME%\config\orb.properties (on Microsoft Windows systems) or $J2EE_HOME/config/orb.properties (on UNIX systems) on the local system. The second line of this file looks like this:

host=localhost

Change localhost to the name of the system on which the J2EE server is running--for example, earth:

host=earth

You can now run the client program as before, but you do not need to specify the option -Dorg.omg.CORBA.ORBInitialHost.



TOC | Prev | Next | Index

This Tutorial contains information on the 1.3.1 version of the Java 2 Platform, Enterprise Edition.

Copyright © 2002 Sun Microsystems, Inc. All rights reserved.