[jboss-cvs] JBoss Messaging SVN: r6433 - in trunk: examples/javaee and 9 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Apr 15 09:07:34 EDT 2009


Author: jmesnil
Date: 2009-04-15 09:07:34 -0400 (Wed, 15 Apr 2009)
New Revision: 6433

Added:
   trunk/examples/javaee/xarecovery/
   trunk/examples/javaee/xarecovery/build.xml
   trunk/examples/javaee/xarecovery/config/
   trunk/examples/javaee/xarecovery/config/jndi.properties
   trunk/examples/javaee/xarecovery/readme.html
   trunk/examples/javaee/xarecovery/src/
   trunk/examples/javaee/xarecovery/src/org/
   trunk/examples/javaee/xarecovery/src/org/jboss/
   trunk/examples/javaee/xarecovery/src/org/jboss/javaee/
   trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/
   trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/XARecoveryReceiverExample.java
   trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/XARecoverySenderExample.java
   trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/server/
   trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/server/XARecoveryExampleBean.java
   trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/server/XARecoveryExampleService.java
Modified:
   trunk/.classpath
   trunk/src/main/org/jboss/messaging/jms/server/recovery/MessagingXAResourceRecovery.java
   trunk/src/main/org/jboss/messaging/jms/server/recovery/MessagingXAResourceWrapper.java
Log:
XA Recovery Example

* added example to show how JMS messages are recovered when JBoss AS restarts after a crash

+ fixed JBMESSAGING-1177: dependency on JMSProviderAdapter

* MessagingXAResourceRecovery no longer uses a JMSProviderAdapter. Instead it looks up directly the XAConnectionFactory used to scan the resources during recovery

Modified: trunk/.classpath
===================================================================
--- trunk/.classpath	2009-04-15 12:36:03 UTC (rev 6432)
+++ trunk/.classpath	2009-04-15 13:07:34 UTC (rev 6433)
@@ -48,6 +48,7 @@
 	<classpathentry kind="src" path="examples/jms/management/src"/>
 	<classpathentry kind="src" path="examples/javaee/ejb-jms-transaction/src"/>
 	<classpathentry kind="src" path="examples/javaee/mdb/src"/>
+	<classpathentry kind="src" path="examples/javaee/xarecovery/src"/>
 	<classpathentry kind="lib" path="thirdparty/apache-log4j/lib/log4j.jar"/>
 	<classpathentry kind="lib" path="thirdparty/junit/lib/junit.jar"/>
 	<classpathentry kind="lib" path="thirdparty/jboss/profiler/jvmti/lib/jboss-profiler-jvmti.jar"/>


Property changes on: trunk/examples/javaee/xarecovery
___________________________________________________________________
Name: svn:ignore
   + build


Added: trunk/examples/javaee/xarecovery/build.xml
===================================================================
--- trunk/examples/javaee/xarecovery/build.xml	                        (rev 0)
+++ trunk/examples/javaee/xarecovery/build.xml	2009-04-15 13:07:34 UTC (rev 6433)
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- =========================================================================================== -->
+<!--                                                                                             -->
+<!-- JBoss, Home of Professional Open Source                                                     -->
+<!-- Copyright 2005, JBoss Inc., and individual contributors as indicated                        -->
+<!-- by the @authors tag. See the copyright.txt in the distribution for a                        -->
+<!-- full listing of individual contributors.                                                    -->
+<!--                                                                                             -->
+<!-- This is free software; you can redistribute it and/or modify it                             -->
+<!-- under the terms of the GNU Lesser General Public License as                                 -->
+<!-- published by the Free Software Foundation; either version 2.1 of                            -->
+<!-- the License, or (at your option) any later version.                                         -->
+<!--                                                                                             -->
+<!-- This software is distributed in the hope that it will be useful,                            -->
+<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of                              -->
+<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU                            -->
+<!-- Lesser General Public License for more details.                                             -->
+<!--                                                                                             -->
+<!-- You should have received a copy of the GNU Lesser General Public                            -->
+<!-- License along with this software; if not, write to the Free                                 -->
+<!-- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA                          -->
+<!-- 02110-1301 USA, or see the FSF site: http://www.fsf.org.                                    -->
+<!--                                                                                             -->
+<!-- =========================================================================================== -->
+
+
+<project default="sender" name="JBoss Messaging XA Recovery Example">
+
+   <import file="../common/build.xml"/>
+
+   <target name="sender">
+      <antcall target="runExample">
+         <param name="example.classname" value="org.jboss.javaee.example.XARecoverySenderExample"/>
+      </antcall>
+   </target>
+
+   <target name="receiver">
+      <antcall target="runExample">
+         <param name="example.classname" value="org.jboss.javaee.example.XARecoveryReceiverExample"/>
+      </antcall>
+   </target>
+    
+</project>
\ No newline at end of file

Added: trunk/examples/javaee/xarecovery/config/jndi.properties
===================================================================
--- trunk/examples/javaee/xarecovery/config/jndi.properties	                        (rev 0)
+++ trunk/examples/javaee/xarecovery/config/jndi.properties	2009-04-15 13:07:34 UTC (rev 6433)
@@ -0,0 +1,3 @@
+java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
+java.naming.provider.url=jnp://localhost:1099
+java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

Added: trunk/examples/javaee/xarecovery/readme.html
===================================================================
--- trunk/examples/javaee/xarecovery/readme.html	                        (rev 0)
+++ trunk/examples/javaee/xarecovery/readme.html	2009-04-15 13:07:34 UTC (rev 6433)
@@ -0,0 +1,199 @@
+<html>
+  <head>
+    <title>JBoss Messaging XA Recovery Example</title>
+    <link rel="stylesheet" type="text/css" href="../../jms/common/common.css">
+  </head>
+  <body>
+     <h1>XA Recovery Example</h1>
+     
+     <p>This example will show how to configure JBoss Messaging XA recovery in JBoss AS (Application Server).</p>
+
+     <p>The example application will invoke an EJB which  will send a JMS message in a transaction.
+        The server will crash while the transaction has not been committed (it is in the prepared state).<br />
+        On server restart, the transaction will be recovered and the JMS message will finally be sent.<br />
+        The example application will then receive the message.<br />
+
+     <h2>Example configuration</h2>
+
+     <p>To run the example, you need to download JBoss AS 5.x and create a configuration for JBoss Messaging.</p>
+     <p>You also need to configure JBoss Transactions to enable XA Recovery of JBoss Messaging resources</p>     
+
+     <h3>JBoss AS configuration</h3>
+     
+     <p>Please refer to JBoss Messaging documentation to deploy it for JBoss AS 5 <span class="missing-doc">add a link to the doc</span></p>
+     
+     <h3>XA Recovery configuration</h3>
+     
+     <p>You need to enable XA Recovery of JBoss Messaging resources.</p>
+     <p>In the <code>jta</code> section of the <code>$JBOSS_HOME/server/jbm2_default/conf/jbossts-properties.xml</code> configuration file, add the
+         property:</p>
+     <pre>
+         <code>&lt;property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.JBMESSAGING1"
+                   value="org.jboss.messaging.jms.server.recovery.MessagingXAResourceRecovery;java:/XAConnectionFactory"/&gt;</code>
+     </pre>
+
+     <p>This informs the Recovery Manager that it can recovers JBoss Messaging XA Resources using the <code>XAConnectionFactory</code> bound to <code>java:/XAConnectionFactory</code> in JNDI
+         (as it is configured in <code>$JBOSS_HOME/server/jbm2_default/deploy/messaging.sar/jbm-jms.xml</code>).</p>
+          
+     <h2>Example step-by-step</h2>
+
+     <p><em>You need to start JBoss AS 5 with the <code>jbm2_default</code> configuration.<br />
+    To deploy the example, type <code>ant deploy</code> from this directory<br />
+    Once the example is deployed in JBoss AS 5, type <code>ant sender</code> to start the example. 
+    This will also crash the server, you will need to restart it.<br />
+    Once it is restarted, type <code>ant receiver</code> to receive the JMS messages which was recovered.<br />
+    Type <code>ant undeploy</code> to undeploy the example from JBoss AS 5.</em></p>
+     
+     The example code is composed of 3 main classes:
+     <dl>
+         <dt><code>XARecoverySenderExample</code></dt>
+         <dd>the client application to invoke the EJB</dd>
+         <dt><code>XARecoveryReceiverExample</code></dt>
+         <dd>the client application to receive a JMS message</dd>
+         <dt><code>XARecoveryExampleBean</code></dt>
+         <dd>a Stateless EJB</dd>
+     </dl>
+     
+     <h3>Example Application</h3>
+     
+     <p>Let's take a look at XARecoverySenderExample first.</p>
+         
+     <ol>
+         <li>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 <a href="config/jndi.properties">jndi.properties</a></li>
+         </li>
+         <pre>
+             <code>InitialContext initialContext = new InitialContext();</code>
+         </pre>
+
+         <li>We look up the EJB</li>
+         <pre>
+             <code>XARecoveryExampleService service = (XARecoveryExampleService)initialContext.lookup("mdb-example/XARecoveryExampleBean/remote");</code>
+         </pre>
+
+         <li>We invoke the EJB's <code>send</code> method. This method will send a JMS text message (with the text passed in parameter)
+             and crash the server when committing the transaction</li>
+         <pre>
+             <code>service.send("This is a text message");</code>
+         </pre>
+
+         <li>And finally, <b>always</b> remember to close your resources after use, in a <code>finally</code> block.</li>
+         
+         <pre>
+             <code>finally
+             {
+                if (initialContext != null)
+                {
+                  initialContext.close();
+                }
+             }</code>
+          </pre>
+     </ol>
+     
+     <h3>EJB Example</h3>
+          
+     <p>Let's now take a look at the EJB example</p>
+     
+     <p>In order to crash the server while a transaction is prepared, we will use a <em>failing</em> <code>XAResource</code>
+         which will crash the server (calling <code>Runtime.halt()</code>) in its commit phase.</p>
+     <p>We will manage ourselves the transaction and its resources enlistment/delistment to be sure that the failing XAResource
+         will crash the server <em>after</em> the JMS XA resources is prepared but <em>before</em> it is committed.</p>
+
+     <ol>
+         <li>First, we create a new initial context</li>
+         <pre>
+             <code>ic = new InitialContext();</code>
+        </pre>
+
+         <li>We look up the Transaction Manager</li>
+         <pre>
+             <code>TransactionManager tm = (TransactionManager)ic.lookup("java:/TransactionManager");</code>
+        </pre>
+
+         <li>We look up the JMS <em>XA</em> Connection Factory (which is bound to <code>java:/JmsXA</code>)</li>
+         <pre>
+             <code>XAConnectionFactory cf = (XAConnectionFactory)ic.lookup("java:/XAConnectionFactory");</code>
+        </pre>
+             
+         <li>We look up the JMS Queue</li>
+         <pre>
+             <code>Queue queue = (Queue)ic.lookup("queue/testQueue");</code>
+        </pre>
+             
+         <li>We create a JMS XA connection, a XA session and a message producer for the queue</li>
+         <pre>
+             <code>xaConnection = xacf.createXAConnection();
+             XASession session = xaConnection.createXASession();
+             MessageProducer messageProducer = session.createProducer(queue);</code>
+        </pre>
+             
+         <li>We create a text message with the text passed in parameter of the EJB method</li>
+         <pre>
+             <code>TextMessage message = session.createTextMessage(text);</code>
+        </pre>
+             
+         <li>We create a <code>FailingXAResource</code>. For this example purpose, this XAResource implementation will
+             call <code>Runtime.halt()</code> from its <code>commit()</code> method</li>
+         <pre>
+             <code>XAResource failingXAResource = new FailingXAResource();</code>
+         </pre>
+
+         <li>We begin the transaction and retrieve it from the transaction manager</li>
+         <pre>
+             <code>tm.begin();
+             Transaction tx = tm.getTransaction();</code>
+         </pre>
+
+         <li>We enlist the failing XAResource</li>
+         <pre>
+             <code>tx.enlistResource(failingXAResource);</code>
+         </pre>
+
+         <li>We enlist the <em>JMS</em> XA Resource</li>
+         <pre>
+             <code>tx.enlistResource(session.getXAResource());</code>
+         </pre>
+
+         <li>We create a text message with the text passed in parameter of the EJB method and send it</li>
+         <pre>
+             <code>TextMessage message = session.createTextMessage(text);
+             messageProducer.send(message);
+             System.out.format("Sent message: %s (%s)\n", message.getText(), message.getJMSMessageID());</code>
+         </pre>
+
+         <li>We delist the failing XAResource</li>
+         <pre>
+             <code>tx.delistResource(failingXAResource);</code>
+         </pre>
+
+         <li>We delist the <em>JMS</em> XA Resource</li>
+         <pre>
+             <code>tx.delistResource(session.getXAResource());</code>
+         </pre>
+         
+         <li>We commit the transaction</li>
+         <pre>
+             <code>System.out.println("committing the tx");
+             tx.commit();</code>
+         </pre>
+         
+         <p>When the transaction is committed, it will prepare both XAResources and then commit them.<br />
+         <p>The failing resources will crash the server leaving the JMS XA Resource <em>prepared</em> but not <em>committed</em></p>
+         
+         <p>You now need to restart the JBoss AS instance.<br />
+         When it is restarted, it will automatically trigger a recovery phase. During that phase, JBoss Messaging resources will be
+         scanned and the <em>prepared</em> transaction will be recovered and committed. It is then possible to consume this message</p>
+         
+         <p>Once the server is restarted, you can run the receiver application (<code>ant receiver</code>). Please note that the JMS MessageID
+             of the received message corresponds to the JMS MessageID printed by the EJB prior to the server crash.</p>
+         
+     <h2>More information</h2>
+     
+     <ul>
+         <li><span class="missing-doc">JBoss Messsaging deployment in JBoss AS 5 </span></li>
+         <li><span class="missing-doc">JBoss Messsaging XA Recovery configuration in JBoss AS 5 </span></li>
+         <li><a href="http://www.jboss.org/jbosstm/">JBoss Transactions</a></li>
+         
+     </ul>
+
+  </body>
+</html>
\ No newline at end of file

Added: trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/XARecoveryReceiverExample.java
===================================================================
--- trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/XARecoveryReceiverExample.java	                        (rev 0)
+++ trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/XARecoveryReceiverExample.java	2009-04-15 13:07:34 UTC (rev 6433)
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.javaee.example;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.MessageConsumer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.naming.InitialContext;
+
+/**
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
+ */
+public class XARecoveryReceiverExample
+{
+   public static void main(String[] args) throws Exception
+   {
+      InitialContext initialContext = null;
+      Connection connection = null;
+      try
+      {
+         // Step 1. Obtain an Initial Context
+         initialContext = new InitialContext();
+
+         // Step 2. Lookup the JMS connection factory
+         ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");
+
+         // Step 3. Lookup the queue
+         Queue queue = (Queue)initialContext.lookup("queue/testQueue");
+
+         // Step 4. Create a connection, a session and a message consumer for the queue
+         connection = cf.createConnection();
+         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         MessageConsumer consumer = session.createConsumer(queue);
+
+         // Step 5. Start the connection
+         connection.start();
+
+         System.out.println("waiting to receive a message...");
+
+         // Step 6. Receive the message sent by the EJB
+         TextMessage messageReceived = (TextMessage)consumer.receive(3600 * 1000);
+         System.out.format("Received message: %s (%s)\n", messageReceived.getText(), messageReceived.getJMSMessageID());
+      }
+      finally
+      {
+         // Step 7. Be sure to close the resources!
+         if (initialContext != null)
+         {
+            initialContext.close();
+         }
+         if (connection != null)
+         {
+            connection.close();
+         }
+      }
+   }
+}

Added: trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/XARecoverySenderExample.java
===================================================================
--- trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/XARecoverySenderExample.java	                        (rev 0)
+++ trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/XARecoverySenderExample.java	2009-04-15 13:07:34 UTC (rev 6433)
@@ -0,0 +1,58 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.javaee.example;
+
+import javax.naming.InitialContext;
+
+import org.jboss.javaee.example.server.XARecoveryExampleService;
+
+/**
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
+ */
+public class XARecoverySenderExample
+{
+   public static void main(String[] args) throws Exception
+   {
+      InitialContext initialContext = null;
+      try
+      {
+         // Step 1. Obtain an Initial Context
+         initialContext = new InitialContext();
+
+         // Step 2. Lookup the EJB
+         XARecoveryExampleService service = (XARecoveryExampleService)initialContext.lookup("mdb-example/XARecoveryExampleBean/remote");
+
+         // Step 3. Invoke the sendAndUpdate method
+         service.send("This is a text message");
+         System.out.println("invoked the EJB service");
+      }
+      finally
+      {
+         // Step 4. Be sure to close the resources!
+         if (initialContext != null)
+         {
+            initialContext.close();
+         }
+      }
+   }
+}

Added: trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/server/XARecoveryExampleBean.java
===================================================================
--- trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/server/XARecoveryExampleBean.java	                        (rev 0)
+++ trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/server/XARecoveryExampleBean.java	2009-04-15 13:07:34 UTC (rev 6433)
@@ -0,0 +1,177 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.javaee.example.server;
+
+import javax.ejb.Remote;
+import javax.ejb.Stateless;
+import javax.ejb.TransactionManagement;
+import javax.ejb.TransactionManagementType;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.TextMessage;
+import javax.jms.XAConnection;
+import javax.jms.XAConnectionFactory;
+import javax.jms.XASession;
+import javax.naming.InitialContext;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+/**
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
+ */
+ at Stateless
+ at Remote(XARecoveryExampleService.class)
+ at TransactionManagement(TransactionManagementType.BEAN)
+public class XARecoveryExampleBean implements XARecoveryExampleService
+{
+
+   public void send(String text) throws Exception
+   {
+      InitialContext ic = null;
+      XAConnection xaConnection = null;
+      try
+      {
+         // Step 1. Create the initial context
+         ic = new InitialContext();
+
+         // Step 2. Lookup the Transaction Manager
+         TransactionManager tm = (TransactionManager)ic.lookup("java:/TransactionManager");
+
+         // Step 3. Look up the XA Connection Factory
+         XAConnectionFactory xacf = (XAConnectionFactory)ic.lookup("java:/XAConnectionFactory");
+
+         // Step 4. Look up the Queue
+         Queue queue = (Queue)ic.lookup("queue/testQueue");
+
+         // Step 5. Create a XA connection, a XA session and a message producer for the queue
+         xaConnection = xacf.createXAConnection();
+         XASession session = xaConnection.createXASession();
+         MessageProducer messageProducer = session.createProducer(queue);
+
+         // Step 6. Create a "fake" XAResource which will crash the server in its commit phase
+         XAResource failingXAResource = new FailingXAResource();
+
+         // Step 7. Begin the transaction
+         tm.begin();
+         Transaction tx = tm.getTransaction();
+
+         // Step 8. Enlist the failing XAResource
+         tx.enlistResource(failingXAResource);
+
+         // Step 9. Enlist the JMS XAResource
+         tx.enlistResource(session.getXAResource());
+
+         // Step 10. Send The Text Message
+         TextMessage message = session.createTextMessage(text);
+         messageProducer.send(message);
+         System.out.format("Sent message: %s (%s)\n", message.getText(), message.getJMSMessageID());
+
+         // Step 12. Delist the failing XAResource
+         tx.delistResource(failingXAResource, XAResource.TMSUCCESS);
+
+         // Step 13. Delist the JMS XAResource
+         tx.delistResource(session.getXAResource(), XAResource.TMSUCCESS);
+
+         // Step 14. Commit the transaction
+         // Both XA Resources will be prepared.
+         // then the failingXAResource will crash the server in its commit phase
+         // and the commit method will never be called on the JMS XA Resource: it will
+         // be in the prepared state when the server crashes
+         System.out.println("committing the tx");
+         tx.commit();
+      }
+      finally
+      {
+         // Step 15. Be sure to close all resources!
+         if (ic != null)
+         {
+            ic.close();
+         }
+         if (xaConnection != null)
+         {
+            xaConnection.close();
+         }
+      }
+   }
+
+   /**
+    * A XAResource which crashes the server in its commit phase
+    */
+   private static class FailingXAResource implements XAResource
+   {
+
+      public void commit(Xid arg0, boolean arg1) throws XAException
+      {
+         System.out.println("########################");
+         System.out.println("# Crashing the server! #");
+         System.out.println("########################");
+         Runtime.getRuntime().halt(1);
+      }
+
+      public void end(Xid arg0, int arg1) throws XAException
+      {
+      }
+
+      public void forget(Xid arg0) throws XAException
+      {
+      }
+
+      public int getTransactionTimeout() throws XAException
+      {
+         return 0;
+      }
+
+      public boolean isSameRM(XAResource arg0) throws XAException
+      {
+         return false;
+      }
+
+      public int prepare(Xid arg0) throws XAException
+      {
+
+         return XAResource.XA_OK;
+      }
+
+      public Xid[] recover(int arg0) throws XAException
+      {
+         return null;
+      }
+
+      public void rollback(Xid arg0) throws XAException
+      {
+      }
+
+      public boolean setTransactionTimeout(int arg0) throws XAException
+      {
+         return false;
+      }
+
+      public void start(Xid arg0, int arg1) throws XAException
+      {
+      }
+
+   }
+}

Added: trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/server/XARecoveryExampleService.java
===================================================================
--- trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/server/XARecoveryExampleService.java	                        (rev 0)
+++ trunk/examples/javaee/xarecovery/src/org/jboss/javaee/example/server/XARecoveryExampleService.java	2009-04-15 13:07:34 UTC (rev 6433)
@@ -0,0 +1,30 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.javaee.example.server;
+
+/**
+ * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
+ */
+public interface XARecoveryExampleService
+{
+   void send(String text) throws Exception;
+}

Modified: trunk/src/main/org/jboss/messaging/jms/server/recovery/MessagingXAResourceRecovery.java
===================================================================
--- trunk/src/main/org/jboss/messaging/jms/server/recovery/MessagingXAResourceRecovery.java	2009-04-15 12:36:03 UTC (rev 6432)
+++ trunk/src/main/org/jboss/messaging/jms/server/recovery/MessagingXAResourceRecovery.java	2009-04-15 13:07:34 UTC (rev 6433)
@@ -23,9 +23,11 @@
 package org.jboss.messaging.jms.server.recovery;
 
 import org.jboss.messaging.core.logging.Logger;
-import org.jboss.tm.XAResourceRecovery;
 
 import javax.transaction.xa.XAResource;
+
+import com.arjuna.ats.jta.recovery.XAResourceRecovery;
+
 import java.util.StringTokenizer;
 
 /**
@@ -45,7 +47,7 @@
 
    private static final Logger log = Logger.getLogger(MessagingXAResourceRecovery.class);
    
-   private String providerAdaptorName;
+   private String xaConnectionFactoryLookupName;
    
    private boolean hasMore;
    
@@ -57,7 +59,7 @@
 
    public MessagingXAResourceRecovery()
    {
-      if(trace) log.trace("Constructing BridgeXAResourceRecovery");
+      if(trace) log.trace("Constructing MessagingXAResourceRecovery");
    }
 
    public boolean initialise(String config)
@@ -73,7 +75,7 @@
          throw new IllegalArgumentException("Must specify provider adaptor name in config");
       }
       
-      providerAdaptorName = tok.nextToken();
+      xaConnectionFactoryLookupName = tok.nextToken();
                   
       //Next two (optional) parameters are the username and password to use for creating the connection
       //for recovery
@@ -90,7 +92,7 @@
          password = tok.nextToken();
       }
          
-      res = new MessagingXAResourceWrapper(providerAdaptorName, username, password);
+      res = new MessagingXAResourceWrapper(xaConnectionFactoryLookupName, username, password);
              
       if (log.isTraceEnabled()) { log.trace(this + " initialised"); }      
       

Modified: trunk/src/main/org/jboss/messaging/jms/server/recovery/MessagingXAResourceWrapper.java
===================================================================
--- trunk/src/main/org/jboss/messaging/jms/server/recovery/MessagingXAResourceWrapper.java	2009-04-15 12:36:03 UTC (rev 6432)
+++ trunk/src/main/org/jboss/messaging/jms/server/recovery/MessagingXAResourceWrapper.java	2009-04-15 13:07:34 UTC (rev 6433)
@@ -18,7 +18,7 @@
  * License along with this software; if not, write to the Free
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */ 
+ */
 
 package org.jboss.messaging.jms.server.recovery;
 
@@ -27,6 +27,8 @@
 import javax.jms.XAConnection;
 import javax.jms.XAConnectionFactory;
 import javax.jms.XASession;
+import javax.naming.Context;
+import javax.naming.InitialContext;
 import javax.transaction.xa.XAException;
 import javax.transaction.xa.XAResource;
 import javax.transaction.xa.Xid;
@@ -43,8 +45,8 @@
  * to retry on failure without having to manually retry
  * 
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * 
  * @author <a href="tim.fox at jboss.com">Tim Fox/a>
+ * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
  * 
  * @version $Revision: 45341 $
  */
@@ -53,54 +55,34 @@
    /** The log */
    private static final Logger log = Logger.getLogger(MessagingXAResourceWrapper.class);
 
-   /** The jms provider name */
-   private String providerName;
-   
+   /** The JNDI lookup for the XA connection factory */
+   private final String xaConnectionFactoryLookupName;
+
    /** The state lock */
    private static final Object lock = new Object();
-   
+
    /** The connection */
    private XAConnection connection;
-   
+
    /** The connectionFactory XAResource */
    private XAResource delegate;
-   
-   private String username;
-   
-   private String password;
-   
-   public MessagingXAResourceWrapper(String providerName, String username, String password)
-   {
-   	this.providerName = providerName;
-   	
-   	this.username = username;
-   	
-   	this.password = password;
-   }
 
-   /**
-    * Get the providerName.
-    * 
-    * @return the providerName.
-    */
-   public String getProviderName()
-   {
-      return providerName;
-   }
+   private final String username;
 
-   /**
-    * Set the providerName.
-    * 
-    * @param providerName the providerName.
-    */
-   public void setProviderName(String providerName)
+   private final String password;
+
+   public MessagingXAResourceWrapper(final String xaConnectionFactoryLookupName, final String username, final String password)
    {
-      this.providerName = providerName;
+      this.xaConnectionFactoryLookupName = xaConnectionFactoryLookupName;
+
+      this.username = username;
+
+      this.password = password;
    }
-   
+
    public Xid[] recover(int flag) throws XAException
    {
-      log.debug("Recover " + providerName);
+      log.debug("Recover " + xaConnectionFactoryLookupName);
       XAResource xaResource = getDelegate();
       try
       {
@@ -114,7 +96,7 @@
 
    public void commit(Xid xid, boolean onePhase) throws XAException
    {
-      log.debug("Commit " + providerName + " xid " + " onePhase=" + onePhase);
+      log.debug("Commit " + xaConnectionFactoryLookupName + " xid " + " onePhase=" + onePhase);
       XAResource xaResource = getDelegate();
       try
       {
@@ -128,7 +110,7 @@
 
    public void rollback(Xid xid) throws XAException
    {
-      log.debug("Rollback " + providerName + " xid ");
+      log.debug("Rollback " + xaConnectionFactoryLookupName + " xid ");
       XAResource xaResource = getDelegate();
       try
       {
@@ -142,7 +124,7 @@
 
    public void forget(Xid xid) throws XAException
    {
-      log.debug("Forget " + providerName + " xid ");
+      log.debug("Forget " + xaConnectionFactoryLookupName + " xid ");
       XAResource xaResource = getDelegate();
       try
       {
@@ -157,7 +139,7 @@
    public boolean isSameRM(XAResource xaRes) throws XAException
    {
       if (xaRes instanceof MessagingXAResourceWrapper)
-         xaRes = ((MessagingXAResourceWrapper) xaRes).getDelegate();
+         xaRes = ((MessagingXAResourceWrapper)xaRes).getDelegate();
 
       XAResource xaResource = getDelegate();
       try
@@ -237,10 +219,10 @@
 
    public void onException(JMSException exception)
    {
-      log.warn("Notified of connection failure in recovery connectionFactory for provider " + providerName, exception);
+      log.warn("Notified of connection failure in recovery connectionFactory for provider " + xaConnectionFactoryLookupName, exception);
       close();
    }
-   
+
    /**
     * Get the connectionFactory XAResource
     * 
@@ -257,23 +239,23 @@
       }
       catch (Exception e)
       {
-      	log.error("********************************Failed to connect to server", e);
+         log.error("********************************Failed to connect to server", e);
          error = e;
       }
 
       if (result == null)
       {
-         XAException xae = new XAException("Error trying to connect to provider " + providerName);
+         XAException xae = new XAException("Error trying to connect to provider " + xaConnectionFactoryLookupName);
          xae.errorCode = XAException.XAER_RMERR;
          if (error != null)
             xae.initCause(error);
          log.debug("Cannot get connectionFactory XAResource", xae);
          throw xae;
       }
-      
+
       return result;
    }
-   
+
    /**
     * Connect to the server if not already done so
     * 
@@ -288,19 +270,19 @@
          if (delegate != null)
             return delegate;
       }
-      
+
       // Create the connection
       XAConnection xaConnection;
-      
+
       if (username == null)
       {
-      	xaConnection = getConnectionFactory().createXAConnection();
+         xaConnection = getConnectionFactory().createXAConnection();
       }
       else
       {
-      	xaConnection = getConnectionFactory().createXAConnection(username, password);
-      }      
-      
+         xaConnection = getConnectionFactory().createXAConnection(username, password);
+      }
+
       synchronized (lock)
       {
          connection = xaConnection;
@@ -332,30 +314,20 @@
     */
    protected XAConnectionFactory getConnectionFactory() throws Exception
    {
-      // Get the JMS Provider Adapter
-      /*if (providerName == null)
-         throw new IllegalArgumentException("Null provider name");
+      // Get the XA Connection Factory
+      if (xaConnectionFactoryLookupName == null)
+         throw new IllegalArgumentException("Null XA ConnectionFactory lookup name");
       Context ctx = new InitialContext();
-      
-      JMSProviderAdapter adapter = (JMSProviderAdapter) ctx.lookup(providerName);
-
-      // Determine the XAConnectionFactory name
-      String connectionFactoryRef = adapter.getFactoryRef();
-      if (connectionFactoryRef == null)
-         throw new IllegalStateException("Provider '" + providerName + "' has no FactoryRef");
-      
-      // Lookup the connection factory
-      ctx = adapter.getInitialContext();
       try
       {
-         return (XAConnectionFactory) Util.lookup(ctx, connectionFactoryRef, XAConnectionFactory.class);
+         return (XAConnectionFactory)ctx.lookup(xaConnectionFactoryLookupName);
       }
       finally
       {
          ctx.close();
-      }*/                             return null;
+      }
    }
-   
+
    /**
     * Close the connection
     */
@@ -391,7 +363,7 @@
    {
       if (e.errorCode == XAException.XA_RETRY)
       {
-         log.debug("Fatal error in provider " + providerName, e);
+         log.debug("Fatal error in provider " + xaConnectionFactoryLookupName, e);
          close();
       }
       throw new XAException(XAException.XAER_RMFAIL);




More information about the jboss-cvs-commits mailing list