| 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
receivemethod 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
QueueConnectionFactoryand 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
finallyblock, automatically closing the session andQueueSenderThe receiving program,
SimpleQueueReceiver.java, performs the following steps:
- Performs a JNDI API lookup of the
QueueConnectionFactoryand 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
finallyblock, automatically closing the session andQueueReceiverThe
receivemethod 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
receivemethod with a timeout argument greater than0:Message m = queueReceiver.receive(1); // 1 millisecond- Call the
receiveNoWaitmethod, which receives a message only if one is available:Message m = queueReceiver.receiveNoWait();The
SimpleQueueReceiverprogram uses an indefinitewhileloop to receive messages, callingreceivewith a timeout argument. CallingreceiveNoWaitwould 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
j2eeadmincommand 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
QueueConnectionFactoryobject 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
SimpleQueueSenderprogram, 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
SimpleQueueReceiverprogram, specifying the queue name. Thejavacommands 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
SimpleQueueReceiverprogram. It displays the queue name and then appears to hang, waiting for messages.In a different terminal window, run the
SimpleQueueSenderprogram. When the messages have been sent, theSimpleQueueReceiverprogram 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
TopicConnectionFactoryand 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
TopicPublisherThe receiving program,
SimpleTopicSubscriber.java, performs the following steps:
- Performs a JNDI API lookup of the
TopicConnectionFactoryand topic- Creates a connection and a session
- Creates a
TopicSubscriber- Creates an instance of the
TextListenerclass 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
qorQ- Closes the connection, which automatically closes the session and
TopicSubscriberThe message listener,
TextListener.java, follows these steps:
- When a message arrives, the
onMessagemethod is called automatically.- The
onMessagemethod converts the incoming message to aTextMessageand 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
j2eeadmincommand 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
TopicConnectionFactoryobject 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
SimpleTopicSubscriberprogram, 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
SimpleTopicPublisherprogram, publishing three messages. Thejavacommands 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
SimpleQueueSenderprogram on one system,mars, and theSimpleQueueReceiverprogram 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 aQueueConnectionFactoryobject, 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.batorsetup.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
TopicConnectionFactoryobject 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
SimpleTopicPublisherand theSimpleTopicSubscriberprograms on two systems calledearthandmars, 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_HOMEenvironment variable and the classpath onmarsso 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 theSimpleTopicSubscriberprogram 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
localhostto 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.