mirror of
https://github.com/apache/activemq-artemis.git
synced 2025-02-27 22:09:18 +00:00
<html> <head> <title>ActiveMQ EJB/JMS Transaction Example</title> <link rel="stylesheet" type="text/css" href="../../common/common.css" /> <link rel="stylesheet" type="text/css" href="../../common/prettify.css" /> <script type="text/javascript" src="../../common/prettify.js"></script> </head> <body onload="prettyPrint()"> <h1>EJB/JMS Transaction Example</h1> <p>The example application will invoke an EJB which is deployed within WildFly which will:</p> <ol> <li>start an XA transaction</li> <li>send a JMS message</li> <li>update an in-memory database</li> <li>commit the transaction</li> </ol> <p>The example application will then receive the message sent by the EJB.</p> <h2>WildFly configuration</h2> <p>The example leverages the Arquillian framework to run a WildFly instance and deploy the MDB.</p> <h2>Example step-by-step</h2> <p><i>download WildFly 8.0.0.Final from <a href="http://wildfly.org/downloads/">here</a> and install.</i></p> <p><i>set the JBOSS_HOME property to point to the WildFly install directory</i></p> <p><i>type <code>mvn verify</code> from the example directory to run</i></p> <p>The example code is composed of two main classes:</p> <ul> <li><code>EJBClientExample</code></li> - the example application <li><code>SendMessageBean</code></li> - a Stateless EJB with a remote interface </ul> <h3>Example Application</h3> <p>Let's take a look at EJBClientExample first.</p> <ol> <li>First we need to get an initial context so we can look-up the EJB. This initial context will get it's properties from the jboss-ejb-client.properties.</li> <pre class="prettyprint"> Properties env = new Properties(); env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); InitialContext initialContext = new InitialContext(); </pre> <li>We look up the EJB</li> <pre class="prettyprint"> SendMessageService service = (SendMessageService) initialContext.lookup("ejb:/test//SendMessageBean!org.apache.activemq.javaee.example.server.SendMessageService"); </pre> <li>We create the DB table which will be updated if it does not already exist</li> <pre class="prettyprint"> service.createTable(); </pre> <li>We invoke the EJB's <code>sendAndUpdate</code> 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</li> <pre class="prettyprint"> service.sendAndUpdate("This is a text message"); </pre> <p><em>We will now consume the JMS message which was sent by the EJB at step 4.</em></p> <li>We need to get a new initial context so we can look-up the JMS connection factory and destination objects from JNDI.</li> <pre class="prettyprint"> 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); </pre> <li>We look up the JMS connection factory</li> <pre class="prettyprint"> ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("jms/RemoteConnectionFactory"); </pre> <li>We lookup the JMS queue</li> <pre class="prettyprint"> Queue queue = (Queue)initialContext.lookup("jms/queues/testQueue"); </pre> <li>We create a connection, a session and a message consumer for the queue</li> <pre class="prettyprint"> connection = cf.createConnection("guest", "password"); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer consumer = session.createConsumer(queue); </pre> <li>We start the JMS connection</li> <pre class="prettyprint"> connection.start(); </pre> <li>We receive a message from the queue. It corresponds to the message sent by the EJB</li> <pre class="prettyprint"> TextMessage messageReceived = (TextMessage)consumer.receive(5000); System.out.println("Received message: " + messageReceived.getText() + " (" + messageReceived.getJMSMessageID() + ")"); </pre> <li>And finally, <b>always</b> remember to close your JMS connections and resources after use, in a <code>finally</code> block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects</li> <pre class="prettyprint"> finally { if (initialContext != null) { initialContext.close(); } if (connection != null) { connection.close(); } } </pre> </ol> <h3>EJB Example</h3> <p>Let's now take a look at the EJB example</p> <ol> <li>First, we create a new initial context</li> <pre class="prettyprint"> ic = new InitialContext(); </pre> <li>We look up the JMS <em>XA</em> Connection Factory (which is bound to <code>java:/JmsXA</code>)</li> <pre class="prettyprint"> ConnectionFactory cf = (ConnectionFactory)ic.lookup("java:/JmsXA"); </pre> <li>We look up the JMS Queue</li> <pre class="prettyprint"> Queue queue = (Queue)ic.lookup("queue/testQueue"); </pre> <li>We create a JMS connection, a session and a message producer for the queue</li> <pre class="prettyprint"> jmsConnection = cf.createConnection(); Session session = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(queue); </pre> <li>We create a text message with the text passed in parameter of the EJB method</li> <pre class="prettyprint"> TextMessage message = session.createTextMessage(text); </pre> <li>We send the message to the queue</li> <pre class="prettyprint"> messageProducer.send(message); System.out.println("Sent message: " + message.getText() + "(" + message.getJMSMessageID() + ")"); </pre> <li>We now lookup the JDBC <em>XA</em> DataSource</li> <pre class="prettyprint"> DataSource ds = (DataSource)ic.lookup("java:/XADS"); </pre> <li>We retrieve a JDBC connection</li> <pre class="prettyprint"> jdbcConnection = ds.getConnection(); </pre> <li>We create a prepared statement to insert the text and message's ID in the DB table</li> <pre class="prettyprint"> PreparedStatement pr = jdbcConnection.prepareStatement("INSERT INTO " + TABLE + " (id, text) VALUES ('" + message.getJMSMessageID() + "', '" + text + "');"); </pre> <li>We execute the prepared statement</li> <pre class="prettyprint"> pr.execute(); </pre> <li>We close the prepared statement</li> <pre class="prettyprint"> pr.close(); </pre> <li>And finally, <b>always</b> remember to close all your connections and resources (for both JMS and JDBC) after use, in a <code>finally</code> block.</li> <pre class="prettyprint"> finally { if (ic != null) { ic.close(); } if (jmsConnection != null) { jmsConnection.close(); } if (jdbcConnection != null) { jdbcConnection.close(); } } </pre> </ol> </body> </html>