EJB/JMS Transaction Example

The example application will invoke an EJB which within the JBoss AS (Application Server) which will:

  1. send a JMS message
  2. update a database from the same transaction

The example application will then receive the message sent by the EJB.
We will also check that the database has been updated as expected.

Example configuration

To run the example, you need to download JBoss AS 5.x and create a configuration for HornetQ.

The example also requires a database. The instructions are for MySQL. If you use another database, please refer to the database documentation to configure it.

The example makes a copy of the default-with-hornetq profile so please configure this for the database

JBoss AS configuration

Please refer to HornetQ Quickstart guide to install it in JBoss AS 5

Database configuration

This example needs a database supporting XA transactions. The instructions are written for MySQL. Please refer to your database documentation to configure it appropriately.

To use MySQL with JBoss AS 5

During the deployment, the example will:

MySQL is configured to connect to a jbossdb database using the jboss/jboss credentials1.

MySQL configuration file defines two DataSources:

Example step-by-step

To deploy and run the server, simply type ./build.sh deploy (or build.bat deploy on windows) from this directory.

Once the second server has started, simply type ./build.sh run (or build.bat run on windows) to run the example .

Simply type ./build.sh undeploy (or build.bat undeploy on windows) to remove the profile from JBoss AS 5.

The example code is composed of two main classes:

Example Application

Let's take a look at EJBClientExample first.

  1. First we need to get an initial context so we can look-up the JMS connection factory and destination objects from JNDI. This initial context will get it's properties from the jndi.properties
  2.             InitialContext initialContext = new InitialContext();
             
  3. We look up the EJB
  4.             SendMessageService service = (SendMessageService)initialContext.lookup("mdb-example/SendMessageBean/remote");
             
  5. We create the DB table which will be updated if it does not already exist
  6.             service.createTable();
             
  7. We invoke the EJB's sendAndUpdate method. This method will send a JMS text message (with the text passed in parameter) and insert a row in the database table with the text and the message's JMS Message ID
  8.             service.sendAndUpdate("This is a text message");
             

    We will now consume the JMS message which was sent by the EJB at step 4.

  9. We look up the JMS connection factory
  10.             ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");
             
  11. We lookup the JMS queue
  12.             Queue queue = (Queue)initialContext.lookup("queue/testQueue");
             
  13. We create a connection, a session and a message consumer for the queue
  14.             connection = cf.createConnection();
                Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                MessageConsumer consumer = session.createConsumer(queue);
             
  15. We start the JMS connection
  16.             connection.start();
             
  17. We receive a message from the queue. It corresponds to the message sent by the EJB
  18.             TextMessage messageReceived = (TextMessage)consumer.receive(5000);
                System.out.println("Received message: " + messageReceived.getText() +
                                             " (" +  messageReceived.getJMSMessageID() + ")");
             
  19. And finally, always remember to close your 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
  20.             finally
                {
                   if (initialContext != null)
                   {
                      initialContext.close();
                   }
                   if (connection != null)
                   {
                      connection.close();
                   }
                 }
              

EJB Example

Let's now take a look at the EJB example

  1. First, we create a new initial context
  2.             ic = new InitialContext();
            
  3. We look up the JMS XA Connection Factory (which is bound to java:/JmsXA)
  4.             ConnectionFactory cf = (ConnectionFactory)ic.lookup("java:/JmsXA");
            
  5. We look up the JMS Queue
  6.             Queue queue = (Queue)ic.lookup("queue/testQueue");
            
  7. We create a JMS connection, a session and a message producer for the queue
  8.             jmsConnection = cf.createConnection();
                Session session = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                MessageProducer messageProducer = session.createProducer(queue);
            
  9. We create a text message with the text passed in parameter of the EJB method
  10.             TextMessage message = session.createTextMessage(text);
            
  11. We send the message to the queue
  12.             messageProducer.send(message);
                System.out.println("Sent message: " + message.getText() + "(" + message.getJMSMessageID() + ")");
            
  13. We now lookup the JDBC XA DataSource
  14.             DataSource ds = (DataSource)ic.lookup("java:/XADS");
            
  15. We retrieve a JDBC connection
  16.             jdbcConnection  = ds.getConnection();
            
  17. We create a prepared statement to insert the text and message's ID in the DB table
  18.             PreparedStatement pr = jdbcConnection.prepareStatement("INSERT INTO " + TABLE
                            + " (id, text) VALUES ('" + message.getJMSMessageID() + "', '" + text + "');");
            
  19. We execute the prepared statement
  20.             pr.execute();
            
  21. We close the prepared statement
  22.             pr.close();
             
  23. And finally, always remember to close all your connections and resources (for both JMS and JDBC) after use, in a finally block.
  24.             finally
                {
                    if (ic != null)
                    {
                       ic.close();
                    }
                    if (jmsConnection != null)
                    {
                       jmsConnection.close();
                    }
                    if (jdbcConnection != null)
                    {
                       jdbcConnection.close();
                    }
                }
            

    More information


    1. Steps to create the MySQL DB
      • connect as root to MySQL: mysql
      • create database jbossdb: create database jbossdb;
      • create user jboss/jboss: GRANT ALL PRIVILEGES ON *.* TO 'jboss'@'%' IDENTIFIED BY 'jboss' WITH GRANT OPTION;
      • disconnect from MySQL
      • check it works: mysql -u jboss -p jbossdb (and type jboss when prompted for the password)