mq5.1-source.src.share.java.examples.jms.README Maven / Gradle / Ivy
The newest version!
Java(TM) Message Service (JMS) CODE EXAMPLES
Notes for use with Oracle GlassFish(tm) Server Message Queue
------------------------------------------------------------
These notes describe the example applications provided in this
directory and explain how to use these examples in a Oracle GlassFish(tm)
Server Message Queue environment. The examples consist of the fifteen
JMS examples included in the JMS Sample Programs bundle available
from the JMS website and four additional examples supplied by the
Oracle GlassFish(tm) Server Message Queue product.
For the most part, the following notes preserve the text that
accompanies the JMS Sample Programs; however, new sections have
been added to provide information specific to Oacle GlassFish(tm)
Server Message Queue.
A detailed guideline on configuring your enrivonment and setting CLASSPATH
is found in the top-level README file of the examples (demo) directory of
the Message Queue installation (/examples/README) as well as in
the "Quick Start Tutorial" in the Oracle GlassFish(tm) Server Message Queue
Developer's Guide.
For running a client application that uses JNDI with File System
Provider, fscontext.jar should be added to the CLASSPATH.
Additional CLASSPATH requirements (if any) are noted with the
description of each example in these notes.
The material in these notes is organized into the following sections:
1. List of example applications
2. Using JMS examples in a Oracle GlassFish(tm) Server Message Queue
environment
- Modification of JMS Sample Programs
- Using Oracle GlassFish(tm) Server Message Queue administered objects and JNDI
- Automatic destination creation
3. JMS Sample Programs
4. Oracle GlassFish(tm) Server Message Queue supplied examples
===============================
1. List of Example Applications
===============================
The example applications consist of the fifteen JMS examples
included in the JMS Sample Programs bundle available from the
JMS website and four additional examples supplied by
Oracle GlassFish(tm) Server Message Queue.
JMS Sample Programs
===================
The JMS Sample Programs bundle can be downloaded in original form
from the JMS website at http://mq.dev.java.net/
The example applications included in the JMS Sample Programs are
the following:
- SenderToQueue
- SynchQueueExample
- SynchTopicExample
- AsynchQueueExample
- AsynchTopicExample
- MessageFormats
- MessageConversion
- ObjectMessages
- BytesMessages
- MessageHeadersTopic
- TopicSelectors
- DurableSubscriberExample
- AckEquivExample
- TransactedExample
- RequestReplyQueue
These examples are described in Section 3 of these notes:
"JMS Sample Programs."
Additional examples supplied by Oracle GlassFish(tm) Server Message Queue
=========================================================================
The additional examples supplied by Oracle GlassFish(tm) Server Message Queue
are the following:
- XMLMessageExample
These examples are described below, in Section 4 of these notes:
"Additional examples supplied by Oracle GlassFish(tm) Server Message Queue."
================================================================================
2. Using JMS Examples in a Oracle GlassFish(tm) Server Message Queue environment
================================================================================
This section provides information you need to run the JMS example
applications in a Oracle GlassFish(tm) Server Message Queue environment.
Modifications to JMS Sample Programs
====================================
All of the examples in JMS Sample Programs use the utility class
SampleUtilities.java to obtain the ConnectionFactory and Destination
administered objects needed by a JMS client application.
As originally written, SampleUtilities.java uses the Java Naming and Directory
Interface (JNDI) to look up these administered objects, thus making the
example applications provider-independent.
In the interest of not requiring JNDI in order to run the example
applications, however, the SampleUtilities.java default behavior has been
modified to directly instantiate Oracle GlassFish(tm) SErver Message Queue
ConnectionFactory and Destination administered objects, rather than use a
JNDI lookup. This means you can run the example applications without having
to first add Oracle GlassFish(tm) Server Message Queue administered objects to a JNDI
directory service.
If you prefer, instead, to use a JNDI lookup, you have to first populate a
JNDI directory service with the required administered objects. Then, when
running an example application, you set the system property USE_JNDI to "true"
on the command line, as shown below:
% java -DUSE_JNDI=true <-D JNDI_Initial_Context_Properties...> \
See the section "Using Oracle GlassFish(tm) Server Message Queue Administered Objects
and JNDI," below, for more details on running these examples with JNDI, including
example values of the JNDI_Initial_Context_Properties.
Using Oracle GlassFish(tm) Server Message Queue Administered Objects and JNDI
=====================================================================
When running the example programs using a JNDI lookup to access Sun
Java(tm) System Message Queue administered objects, you have to perform
the following steps:
1. Add the required Oracle GlassFish(tm) Server Message Queue administered objects
to an object store. Oracle GlassFish(tm) Server Message Queue supports both a file
system service provider and an LDAP service provider.
2. Run the example applications using the appropriate system properties for the JNDI service provider you are using
These steps are described in more detail below.
STEP 1:
Adding the required Oracle GlassFish(tm) Server Message Queue administered objects to
an object store.
-----------------------------------------------------------------------
The examples assume that the lookup name is prefixed with "cn=" that is, for
example, the Queue named "controlQueue" is stored under the lookup name
"cn=controlQueue"
This prefix is meant to satisfy the default Java Schema on most LDAP servers.
If you are using an LDAP server that is configured differently, you have to
modify SampleUtilities.java accordingly.
The examples expect the following Oracle GlassFish(tm) Server Message Queue Objects to
have been created and stored using either a file system or LDAP directory service
provider for JNDI:
1. cn=ConnectionFactory a ConnectionFactory object
2. cn=QueueConnectionFactory a QueueConnectionFactory object
3. cn=TopicConnectionFactory a TopicConnectionFactory object
4. cn=controlQueue a Queue object
5. cn=A a Queue object
6. cn=B a Queue object
7. cn=C a Queue object
8. cn=D a Queue object
9. cn=E a Queue object
(Other Queue and Topic objects of your choice might also be needed
as parameters in running some of the example applications.)
Oracle GlassFish(tm) Server Message Queue administered object support includes both a
command line object manager utility (imqobjmgr) and a GUI tool (the Admin Console).
You use these tools, as described in the Oracle GlassFish(tm) Server Message Queue
Administrator's Guide, to create and manage Oracle GlassFish(tm) Server Message Queue
administered objects. You can find examples in the /examples/imqobjmgr
directory.
The paragraphs below provide examples how to use imqobjmgr to create
administered objects using the following Oracle GlassFish(tm) Server Message
Queue implementations:
- a file system JNDI service provider (A)
- an LDAP JNDI service provider (B).
A) Using the File System Service Provider
The imqobjmgr command is run from the /bin directory.
On the Solaris Platform Edition, imqobjmgr is in the /usr/bin/ directory.
Objects are stored in a directory specified by java.naming.provider.url.
Use the following imqobjmgr command to add an ConnectionFactory
object to the file=based object store.
The lookup name specified is "cn=ConnectionFactory".
Other attributes assume the default connection factory configuration.
% imqobjmgr add -t cf -l cn=ConnectionFactory \
-j "java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory" \
-j "java.naming.provider.url=file:///var/imq/imq_admin_objects"
When running on Windows the value of the "java.naming.provider.url"
property would change to a win32 file url of the form
"file:///C:/imq_admin_objects" which includes the drive letter and full
directory name.
Use the following imqobjmgr command to add a Queue object to the object
store. The lookup name specified is "cn=Queue".
The queue destination name set to "Queue1".
Note: Always use the "JNDI lookup name" for a lookup and not the
"imqDestinationName" that was assigned to the destination object.
% imqobjmgr add -t q -l cn=Queue -o "imqDestinationName=Queue1" \
-j "java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory" \
-j "java.naming.provider.url=file:///var/imq/imq_admin_objects"
B) Using the LDAP Service Provider
The imqobjmgr command is run from the /bin directory.
On the Solaris Platform Edition, imqobjmgr is in the /usr/bin/ directory.
Objects are stored in an LDAP url specified by java.naming.provider.url.
Use the following imqobjmgr command to add a ConnectionFactory
object to the LDAP object store.
The lookup name specified is "cn=ConnectionFactory".
Other attributes assume the default connection factory configuration.
% imqobjmgr add -t cf -l cn=ConnectionFactory \
-j "java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory" \
-j "java.naming.provider.url=ldap://:389/ou=JMSObj, ou=xxx, \
o=JMQ" \
-j "java.naming.security.authentication=simple" \
-j "java.naming.security.principal=uid=xxx, ou=People, o=JMQ" \
-j "java.naming.security.credentials=xxx"
Substitute the , principal, and credential as appropriate.for
Your LDAP installation.
STEP 2:
Run the example using the appropriate JNDI System properties
------------------------------------------------------------
An example of running SenderToQueue (the first JMS example application) with
both the file system (A) and LDAP (B) service providers is included below.
A) Running SenderToQueue with the file system JNDI service provider:
% java -DUSE_JNDI=true \
-Djava.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory \
-Djava.naming.provider.url=file:///var/imq/imq_admin_objects \
SenderToQueue Queue
B) Running SenderToQueue with the LDAP JNDI service provider.
% java -DUSE_JNDI=true \
-D"java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory" \
-D"java.naming.provider.url=ldap://:389/ou=JMSObj, ou=xxx, o=JMQ" \
-D"java.naming.security.authentication=simple" \
-D"java.naming.security.principal=uid=xxx, ou=People, o=JMQ" \
-D"java.naming.security.credentials=xxx" SenderToQueue cn=Queue
Substitute the , principal and credentials as appropriate for
your LDAP installation.
Automatic Destination Creation
==============================
By default, physical destinations for Topics and Queues are "auto-created" by
a broker when a message producer or a message consumer is created, or when
messages are first produced for a destination. Hence, to run the examples,
there is no need to manually create destinations using an administrative tool
(per the JMS Sample Programs instructions in Section 3).
(The "auto-create" behavior can be changed by modifying the Broker properties
"imq.autocreate.queue" and "imq.autocreate.topic".
======================
3. JMS Sample Programs
======================
The Java Message Service (JMS) code examples show how to write a simple
application using JMS. They demonstrate most of the important features of JMS.
The JMS examples are divided into three groups:
- Basic examples provide a simple introduction to JMS. They show how to send
and synchronously receive a single message using either a queue or a topic.
- Intermediate examples demonstrate somewhat more complex features of JMS:
- using message listeners for asynchronous receiving of messages
- using the five supported message formats
- Advanced examples demonstrate still more advanced features of JMS:
- using message headers
- using message selectors
- using durable subscriptions
- using acknowledgement modes
- using transactions
- using the request/reply facility
You can run the simpler queue examples in pairs, each program in a separate
terminal window. This allows you to simulate two separate applications, one
sending a message, the other receiving it.
For the other examples, the producer and consumer (or the publisher and the
subscriber, for topic examples) are each a separate class within the overall
program class. When you run these examples, the two classes use threads to
send and receive messages within the same program.
Before You Start
================
Before you begin, follow the JMS Provider's instructions for starting up the
system. Then create a queue and a topic. Most of the examples take either a
queue name or a topic name as an argument. To run some of the examples, you
should also create a queue named "controlQueue".
Compile the sample programs individually if you wish, or all at once by using
the command
javac *.java
What All the Examples Have in Common
====================================
All the examples use the utility class SampleUtilities.java. It contains the
following methods:
- The methods getConnectionFactory, getQueueConnectionFactory,
getTopicConnectionFactory, getQueue,and getTopic, which obtain a
connection factory or destination either by directly instantiating
Oracle GlassFish(tm) Server Message Queue Administered Objects or, if you
choose to use JNDI, by calling the method jndiLookup.
- The methods sendSynchronizeMessage and receiveSynchronizeMessages, which
are used to ensure that a publisher does not publish messages until its
subscriber or subscribers are ready for message delivery. These methods
use a queue named "controlQueue".
- The class DoneLatch, which allows a program to synchronize between an
asynchronous consumer and another thread in the receiving class.
- An exit method that all the examples call.
Most of the JMS examples execute the same basic setup steps:
1. They read a topic or queue name from the command line.
See "Automatic Destination Creation" in Section 2 of these for
information about automatic destination creation in Oracle GlassFish(tm)
Server Message Queue.
2. They directly instantiate Oracle GlassFish(tm) Server Message Queue connection
factory objects unless the System property USE_JNDI is set to true in
which case they look them up using the jndiLookup method in the class
SampleUtilities.
3. They use the connection factory to create a connection.
4. They use the connection to create a session.
5. They use the session to create message producers and/or consumers for
the topic or queue.
The publish/subscribe examples begin by calling the sendSynchronizeMessage and
receiveSynchronizeMessages methods to ensure that the consumer gets all the
messages the producer sends. The consumer calls sendSynchronizeMessage
when it is ready to receive messages. The producer waits for the synchronize
message; when the message arrives, the producer starts sending its messages.
Most of the message-producing examples send an empty message at the end of the
program to indicate that they have finished sending messages. The
message-consuming examples use this message as a signal to stop reading
messages. The asynchronous message consumers use the DoneLatch class to pass
this signal from the message listener to the consuming class.
Each example contains comments that provide details on what it does and how it
works.
Basic Examples
==============
The most basic JMS examples do the following:
- SenderToQueue.java and SynchQueueExample.java can be used to send and
synchronously receive a single text message using a queue.
If you run these programs in two different windows, the order in which you
start them does not matter. If you run them in the same window, run
SenderToQueue first. Each program takes a queue name as a command-line
argument.
The output of SenderToQueue looks like this (the queue name is SQ):
% java SenderToQueue SQ
Queue name is SQ
Sending message: Here is a message 1
If you use JNDI, the destination name parameter is required to be the
JNDI lookup name and the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> SenderToQueue
Note that is used without the "cn=" prefix.
The output of SynchQueueReceiver looks like this:
% java SynchQueueExample SQ
Queue name is SQ
Reading message: Here is a message
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> SynchQueueExample
Note that is used without the "cn=" prefix.
- SynchTopicExample.java uses a producer class and a consumer class to
publish and synchronously receive a single text message using a topic.
The program takes a topic name as a command-line argument.
The output of SynchTopicExample looks like this (the topic name is ST):
% java SynchTopicExample ST
Topic name is ST
PRODUCER THREAD: Publishing message: Here is a message 1
CONSUMER THREAD: Reading message: Here is a message 1
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> SynchTopicExample
Note that is used without the "cn=" prefix.
These examples contain more detailed explanatory comments than the others.
Intermediate Examples
=====================
The intermediate JMS examples do the following:
- SenderToQueue.java and AsynchQueueExample.java send a specified number of
text messages to a queue and asynchronously receive them using a message
listener (TextListener), which is in the file TextListener.java.
To use SenderToQueue to send more than one message, specify a number after
the queue name when you run the program. For example:
% java SenderToQueue SQ 3
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> SenderToQueue
Note that is used without the "cn=" prefix.
If you run these programs in two different windows, the order in which you
start them does not matter. If you run them in the same window, run
SenderToQueue first.
- AsynchTopicExample.java uses a producer class and a consumer class to
publish five text messages to a topic and asynchronously get them using a
message listener (TextListener).
% java AsynchTopicExample
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> AsynchTopicExample
Note that is used without the "cn=" prefix.
Also, the example expects to find the control queue using the lookup name
"cn=controlQueue".
- MessageFormats.java writes and reads messages in the five supported message
formats. The messages are not sent, so you do not need to specify a queue
or topic argument when you run the program.
% java MessageFormats
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true <-D JNDI_Initial_Context_Properties...>
MessageFormats
- MessageConversion.java shows that for some message formats, you can write
a message using one data type and read it using another. The
StreamMessage format allows conversion between String objects and other
data types. The BytesMessage format allows more limited conversions. You
do not need to specify a queue or topic argument.
% java MessageConversion
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true <-D JNDI_Initial_Context_Properties...>
MessageConversion
- ObjectMessages.java shows that objects are copied into messages, not
passed by reference: once you create a message from a given object, you
can change the original object, but the contents of the message do not
change. You do not need to specify a queue or topic argument.
% java ObjectMessages
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true <-D JNDI_Initial_Context_Properties...>
ObjectMessages
- BytesMessages.java shows how to write, then read, a BytesMessage of
indeterminate length. It reads the message content from a text file, but
the same basic technique can be used with any kind of file, including a
binary one. Specify a text file on the command line when you run the
program:
% java BytesMessages
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> BytesMessages
Advanced Examples
=================
The advanced examples do the following:
- MessageHeadersTopic.java illustrates the use of the JMS message header
fields. It displays the values of the header fields both before and after
a message is sent, and shows how the send method sets the fields.
% java MessageHeadersTopic
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> MessageHeadersTopic
Note that is used without the "cn=" prefix.
Also, the example expects to find the control queue using the lookup name
"cn=controlQueue".
- TopicSelectors.java shows how to use message header fields as message
selectors. The program consists of one publisher and several subscribers.
Each subscriber uses a message selector to receive a subset of the
messages sent by the publisher.
% java TopicSelectors
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> TopicSelectors
Note that is used without the "cn=" prefix.
Also, the example expects to find the control queue using the lookup name
"cn=controlQueue".
- DurableSubscriberExample.java shows how you can create a durable
subscriber that retains messages published to a topic while the subscriber
is inactive.
% java DurableSubscriberExample
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> DurableSubscriberExample \
Note that is used without the "cn=" prefix.
- AckEquivExample.java shows that to ensure that a message will not be
acknowledged until processing is complete, you can use either of the
following methods:
* An asynchronous receiver (message listener) in an AUTO_ACKNOWLEDGE
session
* A synchronous receiver in a CLIENT_ACKNOWLEDGE session
This example takes both a queue name and a topic name as arguments.
% java AckEquivExample
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> AckEquivExample \
Note that and is used without the "cn=" prefix.
Also, the example expects to find the control queue using the lookup name
"cn=controlQueue".
- TransactedExample.java demonstrates the use of transactions in a simulated
e-commerce application. The classes within the example commit a transaction
only after they have received messages they were expecting and have sent
appropriate messages as a result. This example takes an integer argument
(the number of items being ordered). It uses five queues named A, B, C,
D, and E, which you must create in order to run the program.
% java TransactedExample
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> TransactedExample
Note that in this case, the lookup names "cn=A", "cn=B", "cn=C", "cn=D",
and "cn=E" are expected to be available from JNDI.
- RequestReplyQueue.java uses the JMS request/reply facility, which supports
situations in which every message sent requires a response. The sending
application creates a QueueRequestor, which encapsulates the creation and
use of a destination where a reply is sent.
% java RequestReplyQueue
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> RequestReplyQueue
Note that is used without the "cn=" prefix.
============================================================================
4. Additional examples supplied by Oracle GlassFish(tm) Server Message Queue
============================================================================
The additional examples supplied by Oracle GlassFish(tm) Server Message Queue are
the following:
- XMLMessageExample.java reads an XML document from a file and uses the
standard JMS API to send it to a queue. It then uses a receiver to process
the message from the queue as an XML document and convert it to a DOM
object using the JAXP API.
To compile and run the example with JDK1.4 or later, no additional jar libraries are
required.
% java XMLMessageExample []
is the JMS queue to send the message to.
is the file containing the XML document.
is the url to use to resolve relative URLs present in the
input source (i.e. the XML Document)
There is a sample XML file (sample.xml) and its DTD file (sample.dtd)
provided.
for example on a Unix platform -
% java XMLMessageExample myxmlqueue sample.xml file:////
Queue name is myxmlqueue
Write 771 bytes into message
Read 771 bytes from message
Root element of the doc is slideshow
If you use JNDI, the command line would be:
% java -DUSE_JNDI=true \
<-D JNDI_Initial_Context_Properties...> XMLMessageExample
[]
After You Finish
================
After you run the examples, you can delete the topic and queues you created
and shut down the broker.