JMS Bridge Example

This example shows how to configure and run a JMS Bridge in WildFly.
A bridge receives messages from a source JMS destination and forwards them to a target destination.

The source and target destinations can be on different servers, even from different JMS providers. For example, you can use this JMS Bridge to bridge a legacy JMS provider to HornetQ during migration.

This example will show how to configure and run the simplest bridge:

JMS Bridge configuration

The JMS Bridge is configured in the "messaging" subsystem.

The Bridge is deployed in the application server when you simply type ./build.sh deploy (or build.bat deploy on windows) (it is copied to ${JBOSS_HOME}/server/default-with-hornetq/deploy/).

Example step-by-step

download WildFly 8.0.0.Final from here and install.

set the JBOSS_HOME property to point to the WildFly install directory

type mvn verify from the example directory to run

The example is simple: the application will send a message to the source queue and consume the same message from the target queue.

The bridge is configured in the messaging subsystem:

             <jms-bridge name="myBridge">
                 <source>
                 <connection-factory name="ConnectionFactory" />
                 <destination name="queue/sourceQueue" />
                 </source>
                 <target>
                     <connection-factory name="ConnectionFactory" />
                     <destination name="queue/targetQueue" />
                 </target>
                 <quality-of-service>AT_MOST_ONCE</quality-of-service>
                 <failure-retry-interval>1000</failure-retry-interval>
                 <max-retries>7890</max-retries>
                 <max-batch-size>1</max-batch-size>
                 <max-batch-time>1000</max-batch-time>
             </jms-bridge>
     
  1. First we need to get an initial context so we can look up the JMS resources
  2.              final Properties env = new Properties();
    
                 env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
    
                 env.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
    
                 initialContext = new InitialContext(env);
             
  3. We look up the JMS ConnectionFactory
  4.              ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("/jms/RemoteConnectionFactory");
             

    First, we will send a message to the source queue.

  5. We look up the JMS source queue
  6.              Queue sourceQueue = (Queue)initialContext.lookup("jms/queues/sourceQueue");
             
  7. We create a JMS connection, a session and a message producer for the source queue
  8.              sourceConnection = cf.createConnection("guest", "password");
                 Session sourceSession = sourceConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                 MessageProducer sourceProducer = sourceSession.createProducer(sourceQueue);
             
  9. We create and send a message to the source queue. We also display its Message ID.
  10.              TextMessage message = sourceSession.createTextMessage("this is a text message");
                 sourceProducer.send(message);
                 System.out.format("Sent message to %s: %s\n",
                                   ((Queue)message.getJMSDestination()).getQueueName(),
                                   message.getText());
                 System.out.format("Message ID : %s\n", message.getJMSMessageID());
             
  11. We close the source connection
  12.              sourceConnection.close();
             

    Now that a message has been sent to the source queue, we will consume a message from the target queue.
    If the bridge runs correctly, it will have consumed the message from the source and resent it to the target so that we can consume a message from it.

  13. We look up the JMS target queue
  14.              Queue targetQueue = (Queue)initialContext.lookup("jms/queues/targetQueue");
             
  15. We create a connection, a session and a message consumer for the target queue
  16.              targetConnection = cf.createConnection();
                 Session targetSession = targetConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                 MessageConsumer targetConsumer = targetSession.createConsumer(targetQueue);
             
  17. We start the JMS connection to receive messages from the target
  18.              targetConnection.start();
             
  19. We receive a message from the target queue. It has the same content than the message sent to the source queue
  20.              TextMessage messageReceived = (TextMessage)targetConsumer.receive(15000);
                 System.out.format("\nReceived from %s: %s\n",
                               ((Queue)messageReceived.getJMSDestination()).getQueueName(),
                               messageReceived.getText());
                 
             
  21. We now display the received message ID. It is not the same than the ID of the message sent to the source queue. The message received from the target queue was sent by the bridge, not by the source message producer
  22.              System.out.format("Message ID         : %s\n", messageReceived.getJMSMessageID());
             
  23. If you need to retrieve the message ID of the message sent to the source, you can use the property HQ_BRIDGE_MSG_ID_LIST
  24.              System.out.format("Bridged Message ID : %s\n", messageReceived.getStringProperty("HQ_BRIDGE_MSG_ID_LIST"));
             
  25. And finally, always remember to close the JMS connections and resources after use, in a finally block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects
  26.              finally
                 {
                    if (initialContext != null)
                    {
                       initialContext.close();
                    }
                    if (sourceConnection != null)
                    {
                       sourceConnection.close();
                    }
                    if (targetConnection != null)
                    {
                       targetConnection.close();
                    }     
                 }