Chapter 6. Examples
This chapter demonstrates the use of AMQ JMS through example programs.
For more examples, see the AMQ JMS example suite and the Qpid JMS examples.
6.1. Configuring the JNDI context
Applications using JMS typically use JNDI to obtain the ConnectionFactory
and Destination
objects used by the application. This keeps the configuration separate from the program and insulates it from the particular client implementation.
For the purpose of using these examples, a file named jndi.properties
should be placed on the classpath to configure the JNDI context, as detailed previously.
The contents of the jndi.properties
file should match what is shown below, which establishes that the client’s InitialContextFactory
implementation should be used, configures a ConnectionFactory
to connect to a local server, and defines a destination queue named queue
.
# Configure the InitialContextFactory class to use java.naming.factory.initial = org.apache.qpid.jms.jndi.JmsInitialContextFactory # Configure the ConnectionFactory connectionfactory.myFactoryLookup = amqp://localhost:5672 # Configure the destination queue.myDestinationLookup = queue
6.2. Sending messages
This example first creates a JNDI Context
, uses it to look up a ConnectionFactory
and Destination
, creates and starts a Connection
using the factory, and then creates a Session
. Then a MessageProducer
is created to the Destination
, and a message is sent using it. The Connection
is then closed, and the program exits.
A runnable variant of this Sender
example is in the <source-dir>/qpid-jms-examples
directory, along with the Hello World example covered previously in Chapter 3, Getting started.
Example: Sending messages
package org.jboss.amq.example; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.DeliveryMode; import javax.jms.Destination; import javax.jms.ExceptionListener; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import javax.naming.Context; import javax.naming.InitialContext; public class Sender { public static void main(String[] args) throws Exception { try { Context context = new InitialContext(); 1 ConnectionFactory factory = (ConnectionFactory) context.lookup("myFactoryLookup"); Destination destination = (Destination) context.lookup("myDestinationLookup"); 2 Connection connection = factory.createConnection("<username>", "<password>"); connection.setExceptionListener(new MyExceptionListener()); connection.start(); 3 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 4 MessageProducer messageProducer = session.createProducer(destination); 5 TextMessage message = session.createTextMessage("Message Text!"); 6 messageProducer.send(message, DeliveryMode.NON_PERSISTENT, Message.DEFAULT_PRIORITY, Message.DEFAULT_TIME_TO_LIVE); 7 connection.close(); 8 } catch (Exception exp) { System.out.println("Caught exception, exiting."); exp.printStackTrace(System.out); System.exit(1); } } private static class MyExceptionListener implements ExceptionListener { @Override public void onException(JMSException exception) { System.out.println("Connection ExceptionListener fired, exiting."); exception.printStackTrace(System.out); System.exit(1); } } }
- 1
- Creates the JNDI
Context
to look upConnectionFactory
andDestination
objects. The configuration is picked up from thejndi.properties
file as detailed earlier. - 2
- The ConnectionFactory and Destination objects are retrieved from the JNDI Context using their lookup names.
- 3
- The factory is used to create the
Connection
, which then has anExceptionListener
registered and is then started. The credentials given when creating the connection will typically be taken from an appropriate external configuration source, ensuring they remain separate from the application itself and can be updated independently. - 4
- A non-transacted, auto-acknowledge
Session
is created on theConnection
. - 5
- The
MessageProducer
is created to send messages to theDestination
. - 6
- A
TextMessage
is created with the given content. - 7
- The
TextMessage
is sent. It is sent non-persistent, with default priority and no expiration. - 8
- The
Connection
is closed. TheSession
andMessageProducer
are closed implicitly.
Note that this is only an example. A real-world application would typically use a long-lived MessageProducer and send many messages using it over time. Opening and then closing a Connection
, Session
, and MessageProducer
per message is generally not efficient.
6.3. Receiving messages
This example starts by creating a JNDI Context, using it to look up a ConnectionFactory
and Destination
, creating and starting a Connection
using the factory, and then creates a Session
. Then a MessageConsumer
is created for the Destination
, a message is received using it, and its contents are printed to the console. The Connection is then closed and the program exits. The same JNDI configuration is used as in the sending example.
An executable variant of this Receiver
example is contained within the examples directory of the client distribution, along with the Hello World example covered previously in Chapter 3, Getting started.
Example: Receiving messages
package org.jboss.amq.example; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.ExceptionListener; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.Session; import javax.jms.TextMessage; import javax.naming.Context; import javax.naming.InitialContext; public class Receiver { public static void main(String[] args) throws Exception { try { Context context = new InitialContext(); 1 ConnectionFactory factory = (ConnectionFactory) context.lookup("myFactoryLookup"); Destination destination = (Destination) context.lookup("myDestinationLookup"); 2 Connection connection = factory.createConnection("<username>", "<password>"); connection.setExceptionListener(new MyExceptionListener()); connection.start(); 3 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 4 MessageConsumer messageConsumer = session.createConsumer(destination); 5 Message message = messageConsumer.receive(5000); 6 if (message == null) { 7 System.out.println("A message was not received within given time."); } else { System.out.println("Received message: " + ((TextMessage) message).getText()); } connection.close(); 8 } catch (Exception exp) { System.out.println("Caught exception, exiting."); exp.printStackTrace(System.out); System.exit(1); } } private static class MyExceptionListener implements ExceptionListener { @Override public void onException(JMSException exception) { System.out.println("Connection ExceptionListener fired, exiting."); exception.printStackTrace(System.out); System.exit(1); } } }
- 1
- Creates the JNDI
Context
to look upConnectionFactory
andDestination
objects. The configuration is picked up from thejndi.properties
file as detailed earlier. - 2
- The
ConnectionFactory
andDestination
objects are retrieved from the JNDIContext
using their lookup names. - 3
- The factory is used to create the
Connection
, which then has anExceptionListener
registered and is then started. The credentials given when creating the connection will typically be taken from an appropriate external configuration source, ensuring they remain separate from the application itself and can be updated independently. - 4
- A non-transacted, auto-acknowledge
Session
is created on theConnection
. - 5
- The
MessageConsumer
is created to receive messages from theDestination
. - 6
- A call to receive a message is made with a five second timeout.
- 7
- The result is checked, and if a message was received, its contents are printed, or notice that no message was received. The result is cast explicitly to
TextMessage
as this is what we know theSender
sent. - 8
- The
Connection
is closed. TheSession
andMessageConsumer
are closed implicitly.
Note that this is only an example. A real-world application would typically use a long-lived MessageConsumer
and receive many messages using it over time. Opening and then closing a Connection
, Session
, and MessageConsumer
for each message is generally not efficient.