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:
- Creating a connection and a session
- Creating message producers and consumers
- Sending and receiving messages
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:
- Setting your environment to run J2EE clients and applications
- A point-to-point example that uses synchronous receives
- A publish/subscribe example that uses a message listener
- Running JMS client programs on multiple systems
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
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 directoryjms_tutorial/examples/simple
(on UNIX systems) orjms_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:
- Writing the PTP client programs
- Compiling the PTP clients
- Starting the JMS provider
- Creating the JMS administered objects
- Running the PTP clients
- Deleting the queue
4.2.1 Writing the PTP Client Programs
The sending program,
SimpleQueueSender.java
, performs the following steps:
- Performs a Java Naming and Directory InterfaceTM (JNDI) API lookup of the
QueueConnectionFactory
and queue- Creates a connection and a session
- Creates a
QueueSender
- Creates a
TextMessage
- Sends one or more messages to the queue
- Sends a control message to indicate the end of the message stream
- Closes the connection in a
finally
block, automatically closing the session andQueueSender
The receiving program,
SimpleQueueReceiver.java
, performs the following steps:
- Performs a JNDI API lookup of the
QueueConnectionFactory
and queue- Creates a connection and a session
- Creates a
QueueReceiver
- Starts the connection, causing message delivery to begin
- Receives the messages sent to the queue until the end-of-message-stream control message is received
- Closes the connection in a
finally
block, automatically closing the session andQueueReceiver
The
receive
method can be used in several ways to perform a synchronous receive. If you specify no arguments or an argument of0,
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:
- Call the
receive
method with a timeout argument greater than0
:Message m = queueReceiver.receive(1); // 1 millisecond- Call the
receiveNoWait
method, which receives a message only if one is available:Message m = queueReceiver.receiveNoWait();The
SimpleQueueReceiver
program uses an indefinitewhile
loop to receive messages, callingreceive
with a timeout argument. CallingreceiveNoWait
would have the same effect.4.2.2 Compiling the PTP Clients
To compile the PTP example, do the following.
- Make sure that you have set the environment variables shown in Table 4.1.
- At a command line prompt, compile the two source files:
javac SimpleQueueSender.java javac SimpleQueueReceiver.java4.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 -verboseWait 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 namedMyQueue
. The last argument tells the command what kind of destination to create.j2eeadmin -addJmsDestination MyQueue queueTo make sure that the queue has been created, use the following command:
j2eeadmin -listJmsDestinationThis 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
SimpleQueueSender
program, sending three messages. You need to define a value forjms.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 3The 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 3In the same window, run the
SimpleQueueReceiver
program, specifying the queue name. Thejava
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 MyQueueThe 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 3Now 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.In a different terminal window, run the
SimpleQueueSender
program. When the messages have been sent, theSimpleQueueReceiver
program receives them and exits.4.2.6 Deleting the Queue
You can delete the queue you created as follows:
j2eeadmin -removeJmsDestination MyQueueYou 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:
- Writing the pub/sub client programs
- Compiling the pub/sub clients
- Starting the JMS provider
- Creating the JMS administered objects
- Running the pub/sub clients
- Deleting the topic and stopping the server
4.3.1 Writing the Pub/Sub Client Programs
The publishing program,
SimpleTopicPublisher.java
, performs the following steps:
- Performs a JNDI API lookup of the
TopicConnectionFactory
and topic- Creates a connection and a session
- Creates a
TopicPublisher
- Creates a
TextMessage
- Publishes one or more messages to the topic
- Closes the connection, which automatically closes the session and
TopicPublisher
The receiving program,
SimpleTopicSubscriber.java
, performs the following steps:
- Performs a JNDI API lookup of the
TopicConnectionFactory
and topic- Creates a connection and a session
- Creates a
TopicSubscriber
- Creates an instance of the
TextListener
class and registers it as the message listener for theTopicSubscriber
- Starts the connection, causing message delivery to begin
- Listens for the messages published to the topic, stopping when the user enters the character
q
orQ
- Closes the connection, which automatically closes the session and
TopicSubscriber
The message listener,
TextListener.java
, follows these steps:
- When a message arrives, the
onMessage
method is called automatically.- The
onMessage
method converts the incoming message to aTextMessage
and displays its content.4.3.2 Compiling the Pub/Sub Clients
To compile the pub/sub example, do the following.
- Make sure that you have set the environment variables shown in Table 4.1.
- Compile the programs and the message listener class:
javac SimpleTopicPublisher.java javac SimpleTopicSubscriber.java javac TextListener.java4.3.3 Starting the JMS Provider
If you did not do so before, start the J2EE server in another terminal window:
j2ee -verboseWait 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 namedMyTopic
. The last argument tells the command what kind of destination to create.j2eeadmin -addJmsDestination MyTopic topicTo verify that the queue has been created, use the following command:
j2eeadmin -listJmsDestinationThis 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
SimpleTopicSubscriber
program, specifying the topic name. You need to define a value forjms.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 MyTopicThe program displays the following lines and appears to hang:
Topic name is MyTopic To end program, enter Q or q, then <return>- In another terminal window, run the
SimpleTopicPublisher
program, publishing three messages. Thejava
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 3The 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 3In 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 34.3.6 Deleting the Topic and Stopping the Server
- You can delete the topic you created as follows:
j2eeadmin -removeJmsDestination MyTopicYou will use it again in Section 4.4.2, "Communicating Between a J2EE Server and a System Not Running a J2EE Server," however.
- If you wish, you can stop the J2EE server as well:
j2ee -stop4.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 theSimpleQueueReceiver
program on another system,earth
. To do so, follow these steps.
- Start the J2EE server on both systems. Enter the following command in a terminal window on each system:
j2ee -verbose- On
earth
, create aQueueConnectionFactory
object, using a command like the following:j2eeadmin -addJmsFactory jms/EarthQCF queue- On
mars
, create a connection factory with the same name that points to the server onearth
. Enter, on one line, a command like the following:j2eeadmin -addJmsFactory jms/EarthQCF queue -props url=corbaname:iiop:earth:1050#earthYou can modify the script
setup.bat
orsetup.sh
, which you will use in Chapter 10, to automate this command.- 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");- 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 theSimpleTopicSubscriber
programs on two systems calledearth
andmars
, as in Section 4.4.1, but that the J2EE server will be running only onearth
. To specify the system running the server, you can either
- Use the command line, which allows you to access different applications on different servers for maximum flexibility
- Set a configurable property, which allows applications to run only on the system specified in the property
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:
- Start the J2EE server on
earth
:j2ee -verbose- Set the
J2EE_HOME
environment variable and the classpath onmars
so that they point to the J2EE SDK 1.3.1 installation onmars
(see Table 4.1).- 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=hostnameThis 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 theSimpleTopicSubscriber
program onmars
. Make sure that the destination you specify exists on the server running onearth
.
- On a Microsoft Windows system, type the following command:
java -Djms.properties=%J2EE_HOME%\config\jms_client.properties -Dorg.omg.CORBA.ORBInitialHost=earth SimpleTopicSubscriber MyTopic- On a UNIX system, type the following command:
java -Djms.properties=$J2EE_HOME/config/jms_client.properties -Dorg.omg.CORBA.ORBInitialHost=earth SimpleTopicSubscriber MyTopicIf 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=localhostChange
localhost
to the name of the system on which the J2EE server is running--for example,earth
:host=earthYou can now run the client program as before, but you do not need to specify the option
-Dorg.omg.CORBA.ORBInitialHost
.
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.