[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><property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.JBMESSAGING1"
+ value="org.jboss.messaging.jms.server.recovery.MessagingXAResourceRecovery;java:/XAConnectionFactory"/></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