[jboss-svn-commits] JBL Code SVN: r37105 - in labs/jbosstm/trunk/ArjunaJTA/examples: basic and 24 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Jun 22 14:31:53 EDT 2011


Author: mmusgrov
Date: 2011-06-22 14:31:53 -0400 (Wed, 22 Jun 2011)
New Revision: 37105

Added:
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/jta-basic-examples.iml
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/pom.xml
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/main/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/main/java/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/main/java/org/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/main/java/org/jboss/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/main/java/org/jboss/narayana/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/main/java/org/jboss/narayana/examples/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/main/resources/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/FileStoreExample.java
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/HornetqStoreExample.java
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/TransactionExample.java
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/TransactionTimeoutExample.java
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/Util.java
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/VolatileStoreExample.java
   labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/resources/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/pom.xml
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/main/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/main/java/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/main/resources/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/BasicXAExample.java
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/DummyRecovery.java
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/JmsRecovery.java
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/RecoverySetup.java
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/DummyXAResource.java
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/DummyXid.java
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/Util.java
   labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/resources/
Modified:
   labs/jbosstm/trunk/ArjunaJTA/examples/pom.xml
Log:
[JBTM-854] basic and recovery examples

Added: labs/jbosstm/trunk/ArjunaJTA/examples/basic/jta-basic-examples.iml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/basic/jta-basic-examples.iml	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/basic/jta-basic-examples.iml	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/test-annotations" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/target/maven-archiver" />
+      <excludeFolder url="file://$MODULE_DIR$/target/surefire-reports" />
+      <excludeFolder url="file://$MODULE_DIR$/target/test-classes" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Maven: org.jboss.spec.javax.transaction:jboss-transaction-api_1.1_spec:1.0.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.spec.javax.jms:jboss-jms-api_1.1_spec:1.0.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.jbossts:jbossjta:4.15.1.Final" level="project" />
+    <orderEntry type="library" name="Maven: commons-httpclient:commons-httpclient:3.1-jbossorg-1" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.ironjacamar:ironjacamar-spec-api:1.0.0.Beta5" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.javaee:jboss-transaction-api:1.0.1.GA" level="project" />
+    <orderEntry type="library" name="Maven: emma:emma:2.0.5312" level="project" />
+    <orderEntry type="library" name="Maven: emma:emma_ant:2.0.5312" level="project" />
+    <orderEntry type="library" name="Maven: ant:ant:1.6.3" level="project" />
+    <orderEntry type="library" name="Maven: org.hornetq:hornetq-core:2.2.2.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.netty:netty:3.2.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: tanukisoft:wrapper:3.2.3" level="project" />
+    <orderEntry type="library" name="Maven: jacorb:jacorb:2.3.1jboss.patch01-brew" level="project" />
+    <orderEntry type="library" name="Maven: jacorb:idl:2.3.1jboss.patch01-brew" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logmanager:jboss-logmanager:1.2.0.CR7" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.integration:jboss-transaction-spi:6.0.0.CR1" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.integration:jboss-corba-ots-spi:6.0.0.CR1" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.jbossas:jboss-server-manager:1.0.4.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.naming:jnp-client:5.0.5.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss:jboss-common-core:2.2.10.GA" level="project" />
+    <orderEntry type="library" name="Maven: org.picketbox:jbosssx-client:3.0.0.CR2" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: org.picketbox:jboss-security-spi:3.0.0.CR2" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.spec.javax.ejb:jboss-ejb-api_3.1_spec:1.0.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: javax.xml:jaxrpc-api:1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.remoting:jboss-remoting:2.5.3" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.spec.javax.servlet:jboss-servlet-api_3.0_spec:1.0.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.0.0.Beta5" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging-processor:1.0.0.Beta6" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging-generator:1.0.0.Beta6" level="project" />
+    <orderEntry type="library" name="Maven: system:jdk-tools:jdk" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.ws:jbossws-common:2.0.0.Alpha3" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.ws:jbossws-spi:2.0.0.Alpha2" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.ws:jbossws-api:1.0.0-SNAPSHOT" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ant:ant:1.7.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ant:ant-launcher:1.7.1" level="project" />
+    <orderEntry type="library" name="Maven: gnu-getopt:getopt:1.0.13" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.spec.javax.xml.ws:jboss-jaxws-api_2.2_spec:1.0.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.0.Final" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.hornetq:hornetq-jms:2.2.2.Final" level="project" />
+  </component>
+</module>
+

Added: labs/jbosstm/trunk/ArjunaJTA/examples/basic/pom.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/basic/pom.xml	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/basic/pom.xml	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,35 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+	<parent>
+		<groupId>org.jboss.narayana.examples</groupId>
+		<artifactId>jta-examples</artifactId>
+		<version>0.0.1-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+
+	<description>
+	There are 4 basic examples:
+	1. Starting and ending transactions:
+		org.jboss.narayana.examples.basic.TransactionExample
+	2. Setting a transaction timeout:
+		org.jboss.narayana.examples.basic.TransactionTimeoutExample
+	3. A transaction manager stores its commit decision after before deciding to commit a transaction.
+	   This example shows how to change the store type to an (unsafe) in memory store:
+		org.jboss.narayana.examples.basic.VolatileStoreExample
+	4. This example shows how to change the store type to use the fast Hornetq journal:
+		org.jboss.narayana.examples.basic.HornetqStoreExample
+	5. This example shows how to change the store type to a file base store but in directory different from
+	   the default:
+		org.jboss.narayana.examples.basic.FileStoreExample
+
+	To run an example use the maven java exec pluging. For example to run the first example:
+
+	mvn -e exec:java -Dexec.classpathScope=test -Dexec.mainClass=org.jboss.narayana.examples.basic.TransactionExample
+	</description>
+
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>jta-basic-examples</artifactId>
+	<packaging>jar</packaging>
+	<name>Basic Examples</name>
+</project>

Added: labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/FileStoreExample.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/FileStoreExample.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/FileStoreExample.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,25 @@
+package org.jboss.narayana.examples.basic;
+
+import com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean;
+import com.arjuna.common.internal.util.propertyservice.BeanPopulator;
+import junit.framework.Assert;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+import java.io.File;
+
+public class FileStoreExample extends TransactionExample {
+    private static String storeDir = "target/TxStoreDir";
+
+     public static void main(String[] args) throws Exception {
+        setupStore();
+        TransactionExample.main(new String[0]);
+        Assert.assertTrue(new File(storeDir).exists());
+    }
+
+    @BeforeClass
+    public static void setupStore() throws Exception {
+        BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class).setObjectStoreDir(storeDir);
+        Util.emptyObjectStore();
+    }
+}

Added: labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/HornetqStoreExample.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/HornetqStoreExample.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/HornetqStoreExample.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,43 @@
+package org.jboss.narayana.examples.basic;
+
+import com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean;
+import com.arjuna.ats.internal.arjuna.objectstore.hornetq.HornetqJournalEnvironmentBean;
+import com.arjuna.common.internal.util.propertyservice.BeanPopulator;
+import junit.framework.Assert;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.IOException;
+
+public class HornetqStoreExample extends TransactionExample {
+    private static final String storeClassName =  com.arjuna.ats.internal.arjuna.objectstore.hornetq.HornetqObjectStoreAdaptor.class.getName();
+    private static final String storeDir = "target/HornetqStore";
+
+    public static void main(String[] args) throws Exception {
+        setupStore();
+        TransactionExample.main(new String[0]);
+        checkSuccess();
+    }
+
+    @BeforeClass
+    public static void setupStore() throws Exception {
+        File hornetqStoreDir = new File(storeDir);
+
+        BeanPopulator.getDefaultInstance(HornetqJournalEnvironmentBean.class)
+                    .setStoreDir(hornetqStoreDir.getCanonicalPath());
+
+        BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class).setObjectStoreType(storeClassName);
+
+        BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, "default").setObjectStoreType(storeClassName);
+        // TODO figure out why we can't use the hornetqStore as the communications store
+        //BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, "communicationStore").setObjectStoreType(storeClassName);
+
+    }
+
+    @AfterClass
+    public static void checkSuccess() throws Exception {
+        File f = new File(storeDir);
+        Assert.assertTrue(f.exists());
+    }
+}

Added: labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/TransactionExample.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/TransactionExample.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/TransactionExample.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,82 @@
+package org.jboss.narayana.examples.basic;
+
+import javax.transaction.*;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TransactionExample {
+	public static void main(String[] args) throws Exception {
+        TransactionExample txeg = new TransactionExample();
+
+		txeg.commitUserTransaction();
+		txeg.commitTransactionManager();
+        txeg.rollbackUserTransaction();
+        txeg.setRollbackOnly();
+        txeg.transactionStatus();
+	}
+
+	@Test
+	public void commitUserTransaction() throws NotSupportedException, RollbackException, SystemException, HeuristicMixedException, HeuristicRollbackException {
+		//get UserTransaction
+		UserTransaction utx = com.arjuna.ats.jta.UserTransaction.userTransaction();
+
+		// start transaction
+		utx.begin();
+        // ... do some transactional work ...
+		// commit it
+		utx.commit();
+	}
+
+	@Test
+	public void commitTransactionManager() throws NotSupportedException, RollbackException, SystemException, HeuristicMixedException, HeuristicRollbackException {
+		//get TransactionManager
+		TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+
+        // start a transaction by calling begin on the transaction manager
+		tm.begin();
+
+		tm.commit();
+	}
+
+	@Test
+	public void rollbackUserTransaction() throws SystemException, NotSupportedException {
+		UserTransaction utx = com.arjuna.ats.jta.UserTransaction.userTransaction();
+
+		utx.begin();
+
+		// abort the transaction
+		utx.rollback();
+	}
+
+	@Test
+	public void setRollbackOnly() throws SystemException, NotSupportedException, HeuristicRollbackException, HeuristicMixedException {
+		//get TransactionManager
+		TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+
+		// start transaction work..
+		tm.begin();
+
+		// perform transactional work
+		tm.setRollbackOnly();
+        try {
+            tm.commit();
+            throw new RuntimeException("Should have got an exception whilst committing a transaction is marked as rollback only");
+        } catch (RollbackException e) {
+        }
+    }
+
+	@Test
+	public void transactionStatus() throws SystemException, NotSupportedException {
+		UserTransaction utx = com.arjuna.ats.jta.UserTransaction.userTransaction();
+
+		utx.begin();
+
+		// abort the transaction
+		Assert.assertEquals(utx.getStatus(), Status.STATUS_ACTIVE);
+        utx.setRollbackOnly();
+        Assert.assertEquals(utx.getStatus(), Status.STATUS_MARKED_ROLLBACK);
+        utx.rollback();
+        Assert.assertEquals(utx.getStatus(), Status.STATUS_NO_TRANSACTION);
+	}
+}

Added: labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/TransactionTimeoutExample.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/TransactionTimeoutExample.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/TransactionTimeoutExample.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,28 @@
+package org.jboss.narayana.examples.basic;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.transaction.*;
+
+public class TransactionTimeoutExample {
+	public static void main(String[] args) throws Exception {
+        TransactionTimeoutExample txeg = new TransactionTimeoutExample();
+
+        txeg.transactionTimeout();
+	}
+
+	@Test
+	public void transactionTimeout() throws SystemException, NotSupportedException, InterruptedException, HeuristicRollbackException, HeuristicMixedException {
+		UserTransaction utx = com.arjuna.ats.jta.UserTransaction.userTransaction();
+
+        utx.setTransactionTimeout(1);
+		utx.begin();
+        Thread.sleep(1500);
+         try {
+            utx.commit();
+            throw new RuntimeException("Should have got an exception whilst committing a transaction that exceeded its timeout");
+        } catch (RollbackException e) {
+        }
+	}
+}

Added: labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/Util.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/Util.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/Util.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,42 @@
+package org.jboss.narayana.examples.basic;
+
+import com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean;
+import com.arjuna.common.internal.util.propertyservice.BeanPopulator;
+
+import java.io.File;
+
+public class Util {
+    public static void emptyObjectStore() {
+        String objectStoreDirName = BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class).getObjectStoreDir();
+
+        if (objectStoreDirName != null)
+            Util.removeContents(new File(objectStoreDirName));
+    }
+
+    public static void removeContents(File directory)
+    {
+        if ((directory != null) &&
+                directory.isDirectory() &&
+                (!directory.getName().equals("")) &&
+                (!directory.getName().equals("/")) &&
+                (!directory.getName().equals("\\")) &&
+                (!directory.getName().equals(".")) &&
+                (!directory.getName().equals("..")))
+        {
+            File[] contents = directory.listFiles();
+
+            for (File f : contents) {
+                if (f.isDirectory()) {
+                    removeContents(f);
+
+                    f.delete();
+                } else {
+                    f.delete();
+                }
+            }
+        }
+
+        if (directory != null)
+            directory.delete();
+    }
+}

Added: labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/VolatileStoreExample.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/VolatileStoreExample.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/basic/src/test/java/org/jboss/narayana/examples/basic/VolatileStoreExample.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,35 @@
+package org.jboss.narayana.examples.basic;
+
+import com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean;
+import com.arjuna.common.internal.util.propertyservice.BeanPopulator;
+import junit.framework.Assert;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+import java.io.File;
+
+public class VolatileStoreExample extends TransactionExample {
+    private static final String storeClassName = com.arjuna.ats.internal.arjuna.objectstore.VolatileStore.class.getName();
+    private static String defaultStoreDir;
+
+    public static void main(String[] args) throws Exception {
+        setupStore();
+        TransactionExample.main(new String[0]);
+        checkSuccess();
+    }
+
+    @BeforeClass
+    public static void setupStore() throws Exception {
+        Util.emptyObjectStore();
+        defaultStoreDir = BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class).getObjectStoreDir();
+
+        BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, "default").setObjectStoreType(storeClassName);
+        BeanPopulator.getNamedInstance(ObjectStoreEnvironmentBean.class, "communicationStore").setObjectStoreType(storeClassName);
+    }
+
+    @AfterClass
+    public static void checkSuccess() throws Exception {
+        File f = new File(defaultStoreDir);
+        Assert.assertTrue(!f.exists());
+    }
+}
\ No newline at end of file

Modified: labs/jbosstm/trunk/ArjunaJTA/examples/pom.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/pom.xml	2011-06-22 16:32:35 UTC (rev 37104)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/pom.xml	2011-06-22 18:31:53 UTC (rev 37105)
@@ -1,30 +1,183 @@
-<?xml version="1.0"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <!-- JBoss, Home of Professional Open Source Copyright 2009, Red Hat Middleware 
-		LLC, and individual contributors as indicated by the @author tags. See the 
-		copyright.txt in the distribution for a full listing of individual contributors. 
-		This copyrighted material is made available to anyone wishing to use, modify, 
-		copy, or redistribute it subject to the terms and conditions of the GNU Lesser 
-		General Public License, v. 2.1. This program is distributed in the hope that 
-		it will be useful, but WITHOUT A 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, v.2.1 along with this distribution; 
-		if not, write to the Free Software Foundation, Inc., 51 Franklin Street, 
-		Fifth Floor, Boston, MA 02110-1301, USA. (C) 2009, @author JBoss Inc. (jonathan.halliday at redhat.com) -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.jboss.narayana</groupId>
         <artifactId>jbossjta-all</artifactId>
         <version>5.0.0.M1-SNAPSHOT</version>
-	<relativePath>../pom.xml</relativePath>
+        <relativePath>../pom.xml</relativePath>
     </parent>
-    <modelVersion>4.0.0</modelVersion>
     <artifactId>jbossjta-examples</artifactId>
     <packaging>pom</packaging>
     <name>All examples of JBoss JTA</name>
     <description>All examples of JBoss JTA</description>
-    <modules>
-        <module>simple_maven_example</module>
-        <module>simple_integration_example</module>
-    </modules>
+
+	<repositories>
+		<repository>
+			<id>jboss-public-repository-group</id>
+			<name>JBoss Public Maven Repository Group</name>
+			<url>https://repository.jboss.org/nexus/content/groups/public/</url>
+			<releases>
+				<enabled>true</enabled>
+			</releases>
+			<snapshots>
+				<enabled>true</enabled>
+			</snapshots>
+		</repository>
+	</repositories>
+
+   	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<configuration>
+					<configuration>
+						<skipTests>false</skipTests>
+					</configuration>
+
+					<forkMode>pertest</forkMode>
+					<workingDirectory>target/test-classes</workingDirectory>
+					<runOrder>alphabetical</runOrder>
+					<redirectTestOutputToFile>true</redirectTestOutputToFile>
+					<inherited>true</inherited>
+					<includes>
+						<include>**/*.java</include>
+					</includes>
+					<excludes>
+						<exclude>**/Util.java</exclude>
+					</excludes>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<configuration>
+					<testClassesDirectory>true</testClassesDirectory>
+					<archive>
+						<manifest>
+							<addClasspath>true</addClasspath>
+						</manifest>
+					</archive>
+				</configuration>
+	  		</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+	  		</plugin>
+	  <!--
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<configuration>
+					<configuration>
+						<skipTests>true</skipTests>
+					</configuration>
+
+					<forkMode>pertest</forkMode>
+					<workingDirectory>target/test-classes</workingDirectory>
+					<runOrder>alphabetical</runOrder>
+					<redirectTestOutputToFile>true</redirectTestOutputToFile>
+					<inherited>true</inherited>
+					<includes>
+						<include>**/*.java</include>
+					</includes>
+				</configuration>
+			</plugin>
+			-->
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<configuration>
+					<archive>
+						<manifest>
+							<mainClass>org.jboss.narayana.examples.XAResourceTest</mainClass>
+							<addClasspath>true</addClasspath>
+						</manifest>
+						<manifestEntries>
+							<mode>development</mode>
+							<url>${pom.url}</url>
+						</manifestEntries>
+					</archive>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-clean-plugin</artifactId>
+				<version>2.4.1</version>
+				<configuration>
+	  				<filesets>
+						<fileset>
+		  					<directory>PutObjectStoreDirHere</directory>
+						</fileset>
+						<fileset>
+		  					<directory>ObjectStore</directory>
+						</fileset>
+	  				</filesets>
+				</configuration>
+  			</plugin>
+
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.jboss.spec.javax.transaction</groupId>
+			<artifactId>jboss-transaction-api_1.1_spec</artifactId>
+			<version>1.0.0.Final</version>
+		</dependency>
+		<dependency>
+			<groupId>org.jboss.spec.javax.jms</groupId>
+			<artifactId>jboss-jms-api_1.1_spec</artifactId>
+			<version>1.0.0.Final</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.jboss.jbossts</groupId>
+			<artifactId>jbossjta</artifactId>
+			<version>4.15.1.Final</version>
+			<exclusions>
+				<exclusion>
+					<groupId>org.jboss.logging</groupId>
+					<artifactId>jboss-logging-spi</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.6</version>
+			<scope>test</scope>
+		</dependency>
+
+		<!-- Embedded Hornetq -->
+		<dependency>
+			<groupId>org.hornetq</groupId>
+			<artifactId>hornetq-core</artifactId>
+			<version>2.2.2.Final</version>
+		</dependency>
+		<dependency>  
+		   <groupId>org.hornetq</groupId>  
+		   <artifactId>hornetq-jms</artifactId>  
+		   <version>2.2.2.Final</version>  
+		</dependency>  
+		<dependency>
+			<groupId>org.jboss.netty</groupId>
+			<artifactId>netty</artifactId>
+			<version>3.2.0.Final</version>
+		</dependency>
+	</dependencies>
+
+	<modules>
+		<module>basic</module>
+		<module>recovery</module>
+		<module>simple_maven_example</module>
+		<module>simple_integration_example</module>
+	</modules>
 </project>

Added: labs/jbosstm/trunk/ArjunaJTA/examples/recovery/pom.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/recovery/pom.xml	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/recovery/pom.xml	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,69 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+	<parent>
+		<groupId>org.jboss.narayana.examples</groupId>
+		<artifactId>jta-examples</artifactId>
+		<version>0.0.1-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+
+	<description>
+    There are 3 recovery examples:
+    1. An example showing how to manually enlist (2 dummy) resources (without failures)
+		org.jboss.narayana.examples.recovery.BasicXAExample
+	2. An example demonstrating recovery from failures after prepare but before commit using Dummy XA resources:
+		org.jboss.narayana.examples.recovery.DummyRecovery
+
+	   This example needs to be run twice the first run (controled by a command line arg of -f, for fail)
+	   will halt the VM thus generating a "recovery record".
+	   The second run (ontroled by a command line arg of -r, for recover) will cause the transaction manager
+	   recovery system to replay the commit phase of the transaction.
+	3. Another example demonstrating recovery from failures but using JMS XA resources (instead of dummy ones).
+		Again the first run will generate 2 messages and leave the transaction dangling in the prepared state.
+		The second run will trigger the recovery system which in turn commits the two prepared JMS XA resources.
+		Then the two messages are consumed.
+
+    To run an example use the maven java exec pluging. For example to run the second recovery example:
+
+	 mvn -e exec:java -Dexec.mainClass=org.jboss.narayana.examples.recovery.DummyRecovery -Dexec.classpathScope=test -Dexec.args="-r"
+	  mvn -e exec:java -Dexec.mainClass=org.jboss.narayana.examples.recovery.DummyRecovery -Dexec.classpathScope=test -Dexec.args="-f"
+
+    And to run the JMS recovery example:
+
+	 mvn -e exec:java -Dexec.mainClass=org.jboss.narayana.examples.recovery.JmsRecovery -Dexec.classpathScope=test -Dexec.args="-r"
+	 mvn -e exec:java -Dexec.mainClass=org.jboss.narayana.examples.recovery.JmsRecovery -Dexec.classpathScope=test -Dexec.args="-f"
+
+	On the second step of each example you will see a warning
+	   (HornetQException[errorCode=4 message=The connection was disconnected because of server shutdown])
+	which can be ignored. It caused by the recovery subsystem not performing an orderly shutdown of JMS
+	communications. This will be fixed in the next revision of JBossTS.
+
+	And finally, to read the (binary) hornetq logs use the PrintData tool:
+
+	mvn -e exec:java -Dexec.mainClass=org.hornetq.core.persistence.impl.journal.PrintData -Dexec.classpathScope=test -Dexec.args="target/data/hornetq/bindings target/data/hornetq/largemessages"
+
+	</description>
+
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>jta-recovery-examples</artifactId>
+	<packaging>jar</packaging>
+	<name>Recovery Examples</name>
+
+   	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<configuration>
+					<!-- some recovery tests need to halt the JVM in order to demonstrate recovery
+					     so we must skip the tests -->
+					<excludes>
+						<exclude>**/RecoverySetup.java</exclude>
+						<exclude>**/*.java</exclude>
+					</excludes>
+				</configuration>
+			</plugin>
+		</plugins>
+   	</build>
+</project>

Added: labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/BasicXAExample.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/BasicXAExample.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/BasicXAExample.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,52 @@
+package org.jboss.narayana.examples.recovery;
+
+import junit.framework.Assert;
+import org.jboss.narayana.examples.util.DummyXAResource;
+import org.jboss.narayana.examples.util.Util;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.transaction.*;
+
+public class BasicXAExample extends RecoverySetup {
+    public static void main(String[] args) throws Exception {
+        startRecovery();
+        new BasicXAExample().resourceEnlistment();
+        stopRecovery();
+    }
+
+    @BeforeClass
+    public static void beforeClass() {
+        startRecovery();
+    }
+
+    @AfterClass
+    public static void afterClass() {
+        stopRecovery();
+    }
+
+    @Test
+    public void resourceEnlistment() throws NotSupportedException, RollbackException, SystemException, HeuristicMixedException, HeuristicRollbackException {
+        // obtain a reference to the transaction manager
+        TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+        DummyXAResource xares1 = new DummyXAResource(DummyXAResource.faultType.NONE);
+        DummyXAResource xares2 = new DummyXAResource(DummyXAResource.faultType.NONE);
+
+        // start a transaction
+        tm.begin();
+
+        // enlist some resources
+        tm.getTransaction().enlistResource(xares1);
+        tm.getTransaction().enlistResource(xares2);
+
+        Assert.assertTrue(xares1.startCalled);
+
+        // commit any transactional work that was done on the two dummy XA resources
+        tm.commit();
+
+        Assert.assertTrue(xares1.endCalled);
+        Assert.assertTrue(xares1.prepareCalled);
+        Assert.assertTrue(xares1.commitCalled);
+    }
+}

Added: labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/DummyRecovery.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/DummyRecovery.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/DummyRecovery.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,75 @@
+package org.jboss.narayana.examples.recovery;
+
+import com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean;
+import com.arjuna.common.internal.util.propertyservice.BeanPopulator;
+import junit.framework.Assert;
+import org.jboss.narayana.examples.util.DummyXAResource;
+import org.jboss.narayana.examples.util.Util;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.transaction.*;
+
+public class DummyRecovery extends RecoverySetup {
+
+    public static void main(String[] args) throws Exception {
+        if (args.length == 1) {
+            if (args[0].equals("-f")) {
+                BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class).setObjectStoreDir(Util.recoveryStoreDir);
+                new DummyRecovery().enlistmentFailure();
+            } else if (args[0].equals("-r")) {
+                startRecovery();
+                new DummyRecovery().waitForRecovery();
+                stopRecovery();
+            }
+        } else {
+            System.err.println("to generate something to recover: java DummyRecovery -f");
+            System.err.println("to recover after failure: java DummyRecovery -r");
+        }
+    }
+
+    @BeforeClass
+    public static void beforeClass() {
+        startRecovery();
+    }
+
+    @AfterClass
+    public static void afterClass() {
+        stopRecovery();
+    }
+
+    @Test
+    public void enlistmentFailure() throws NotSupportedException, RollbackException, SystemException, HeuristicMixedException, HeuristicRollbackException {
+        if (Util.countLogRecords() != 0)
+            return;
+
+        // obtain a reference to the transaction manager
+        TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+
+        // start a transaction
+        tm.begin();
+
+        // enlist some resources
+        tm.getTransaction().enlistResource(new DummyXAResource(DummyXAResource.faultType.NONE));
+        tm.getTransaction().enlistResource(new DummyXAResource(DummyXAResource.faultType.HALT));
+
+        // commit any transactional work that was done on the two dummy XA resources
+        System.out.println("Halting VM - next test run will not halt and should pass since there will be transactions to recover");
+
+        tm.commit();
+    }
+
+    @Test
+    public void waitForRecovery() throws InterruptedException {
+        int commitRequests = DummyXAResource.getCommitRequests();
+        recoveryManager.scan();
+
+        if (commitRequests >= DummyXAResource.getCommitRequests())
+            System.err.println("Did you forget to generate a recovery record before testing recovery (use the -f argument)");
+
+        Assert.assertTrue(commitRequests < DummyXAResource.getCommitRequests());
+
+        Util.emptyObjectStore();
+    }
+}

Added: labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/JmsRecovery.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/JmsRecovery.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/JmsRecovery.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,368 @@
+package org.jboss.narayana.examples.recovery;
+
+import com.arjuna.ats.jta.common.JTAEnvironmentBean;
+import com.arjuna.common.internal.util.propertyservice.BeanPopulator;
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.api.jms.HornetQJMSClient;
+import org.hornetq.api.jms.JMSFactoryType;
+import org.hornetq.core.config.Configuration;
+import org.hornetq.core.config.impl.ConfigurationImpl;
+import org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory;
+import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory;
+import org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory;
+import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
+import org.hornetq.core.server.JournalType;
+import org.hornetq.jms.client.HornetQConnectionFactory;
+import org.hornetq.jms.server.config.ConnectionFactoryConfiguration;
+import org.hornetq.jms.server.config.JMSConfiguration;
+import org.hornetq.jms.server.config.JMSQueueConfiguration;
+import org.hornetq.jms.server.config.impl.ConnectionFactoryConfigurationImpl;
+import org.hornetq.jms.server.config.impl.JMSConfigurationImpl;
+import org.hornetq.jms.server.config.impl.JMSQueueConfigurationImpl;
+import org.hornetq.jms.server.embedded.EmbeddedJMS;
+import org.hornetq.jms.server.recovery.HornetQXAResourceRecovery;
+import org.hornetq.utils.UUIDGenerator;
+import org.jboss.narayana.examples.util.DummyXAResource;
+import org.jboss.narayana.examples.util.DummyXid;
+import org.jboss.narayana.examples.util.Util;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.jms.*;
+import javax.transaction.*;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import java.util.ArrayList;
+import java.util.List;
+
+public class JmsRecovery extends RecoverySetup {
+    private static EmbeddedJMS jmsServer;
+    private static HornetQConnectionFactory xacf;
+    private static Queue queue;
+    private static boolean inVM = true;
+
+    public static void main(String[] args) throws Exception {
+
+        if (args.length == 1) {
+            startServices();
+
+            if (args[0].equals("-f")) {
+                new JmsRecovery().testXAWithErrorPart1();
+            } else if (args[0].equals("-r")) {
+                startRecovery();
+                new JmsRecovery().testXAWithErrorPart2();
+            }
+
+            stopServices();
+        }
+
+        System.err.println("to generate something to recover: java JmsRecovery -f");
+        System.err.println("to recover from the failure: java JmsRecovery -r");
+    }
+
+    @BeforeClass
+    public static void startServices() throws Exception
+    {
+        startHornetq();
+        startRecovery();
+    }
+
+    @AfterClass
+    public static void stopServices() throws Exception
+    {
+        stopRecovery();
+        stopHornetq();
+    }
+
+    private static void startHornetq() throws Exception {
+        /*
+         * Step 1. Decide whether to use inVM or remote communications:
+         *  clients connect to servers by obtaining connections from a ConnectorFactory
+         *  servers accept connections from clients by obtaining acceptors from an AcceptorFactory
+         */
+        String acceptorName = inVM ? InVMAcceptorFactory.class.getName() : NettyAcceptorFactory.class.getName();
+        String connFacName = inVM ? InVMConnectorFactory.class.getName() :NettyConnectorFactory.class.getName();
+
+        String queueName = "/queue/queue1";
+
+        startHornetqServer(acceptorName, connFacName, queueName);
+        initialiseHornetqClient(connFacName, queueName);
+    }
+
+    private static void stopHornetq() throws Exception {
+        xacf.close();
+        jmsServer.stop();
+    }
+
+    public static void startRecovery() {
+        String resourceRecoveryClass = HornetQXAResourceRecovery.class.getName();
+        String inVMResourceRecoveryOpts = org.hornetq.core.remoting.impl.invm.InVMConnectorFactory.class.getName();
+        String remoteResourceRecoveryOpts = org.hornetq.core.remoting.impl.netty.NettyConnectorFactory.class.getName();
+
+        /*
+         * Tell JBossTS how to recover Hornetq resources. To do it via jbossts-properties.xml use
+         *  <entry key="JTAEnvironmentBean.xaResourceRecoveryClassNames">
+         */
+        List<String> recoveryClassNames = new ArrayList<String>();
+
+        if (inVM)
+            recoveryClassNames.add(resourceRecoveryClass + ";" + inVMResourceRecoveryOpts);
+        else
+            recoveryClassNames.add(resourceRecoveryClass + ";" + remoteResourceRecoveryOpts);
+
+        BeanPopulator.getDefaultInstance(JTAEnvironmentBean.class).setXaResourceRecoveryClassNames(recoveryClassNames);
+
+        RecoverySetup.startRecovery();
+    }
+
+    private static void startHornetqServer(String acceptorName, String connFacName, String queueName) throws Exception
+    {
+        // Step 2. Create the server configuration
+        Configuration configuration = new ConfigurationImpl();
+
+        configuration.setPersistenceEnabled(true);
+        configuration.setSecurityEnabled(false);
+        configuration.setJournalType(JournalType.NIO);
+        configuration.setJournalDirectory(Util.hornetqStoreDir);
+        configuration.setBindingsDirectory(Util.hornetqStoreDir + "/bindings");
+        configuration.setLargeMessagesDirectory(Util.hornetqStoreDir + "/largemessages");
+
+        configuration.getAcceptorConfigurations().add(new TransportConfiguration(acceptorName));
+        configuration.getConnectorConfigurations().put("connector", new TransportConfiguration(connFacName));
+
+        // Step 3. Create the JMS configuration
+        JMSConfiguration jmsConfig = new JMSConfigurationImpl();
+
+        // Step 4. Configure the JMS ConnectionFactory
+        ArrayList<String> connectorNames = new ArrayList<String>();
+        connectorNames.add("connector");
+        ConnectionFactoryConfiguration cfConfig = new ConnectionFactoryConfigurationImpl("cf", true,  connectorNames, "/cf");
+        jmsConfig.getConnectionFactoryConfigurations().add(cfConfig);
+
+        // Step 5. Configure the JMS Queue
+        JMSQueueConfiguration queueConfig = new JMSQueueConfigurationImpl("queue1", null, true, queueName);
+        jmsConfig.getQueueConfigurations().add(queueConfig);
+
+        // Step 6. Start the JMS Server using the HornetQ core server and the JMS configuration
+        jmsServer = new EmbeddedJMS();
+        jmsServer.setConfiguration(configuration);
+        jmsServer.setJmsConfiguration(jmsConfig);
+        jmsServer.start();
+
+        System.out.println("Embedded JMS Server is running");
+    }
+
+    // Step 6 Initialise client side objects: connection factory and JMS queue
+    private static void initialiseHornetqClient(String connFacName, String queueName) {
+        xacf = HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.XA_CF, new TransportConfiguration(connFacName));
+        queue = (Queue)jmsServer.lookup(queueName);
+    }
+
+    private void endTx(XAResource xaRes, Xid xid, boolean commit) throws XAException {
+        xaRes.end(xid, XAResource.TMSUCCESS);
+        xaRes.prepare(xid);
+        if (commit)
+            xaRes.commit(xid, false);
+        else
+            xaRes.rollback(xid);
+    }
+
+    private Xid startTx(XAResource xaRes) throws XAException {
+        Xid xid = new DummyXid("xa-example1".getBytes(), 1, UUIDGenerator.getInstance()
+                    .generateStringUUID()
+                    .getBytes());
+
+        xaRes.start(xid, XAResource.TMNOFLAGS);
+
+        return xid;
+    }
+
+    private void startJTATx(XAResource ... resources) throws XAException, SystemException, NotSupportedException, RollbackException {
+        TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+
+        tm.begin();
+
+        for (XAResource xaRes : resources)
+            tm.getTransaction().enlistResource(xaRes);
+    }
+
+    private void endJTATx(boolean commit) throws SystemException, RollbackException, HeuristicRollbackException, HeuristicMixedException {
+        TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+
+        // no need to delist resources since that is done automatically by a JTA compliant TM
+        if (commit)
+            tm.commit();
+        else
+            tm.rollback();
+    }
+
+    private void produceMessages(XAConnection connection, String ... msgs) throws Exception{
+        // Create an XA session and a message producer
+        //Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        Session session = connection.createXASession();
+        MessageProducer producer = session.createProducer(queue);
+
+        for (String msg : msgs)
+            producer.send(session.createTextMessage(msg));
+
+        producer.close();
+        session.close();
+    }
+
+    public void produceMessages(DummyXAResource.faultType fault, String ... messages) throws Exception {
+        XAConnection connection = xacf.createXAConnection();
+
+        try
+        {
+            connection.start();
+
+            // Begin some Transaction work
+            XASession xaSession = connection.createXASession();
+            XAResource xaRes = xaSession.getXAResource();
+
+            //Xid xid = startTx(xaRes);
+            startJTATx(new DummyXAResource(fault), xaRes);
+
+
+            produceMessages(connection, messages);
+
+            endJTATx(true);
+        }
+        finally
+        {
+             connection.close();
+        }
+    }
+
+    private int consumeMessages(MessageConsumer consumer, long millis, int cnt) throws JMSException {
+        for (int i = 0; i < cnt; i++) {
+            TextMessage tm = (TextMessage) consumer.receive(millis);
+            if (tm == null)
+                return i;
+
+            System.out.println("Message received: " + tm.getText());
+        }
+
+        return cnt;
+    }
+
+    public int consumeMessages(int cnt, long millis) throws Exception {
+        XAConnection connection = xacf.createXAConnection();
+        int msgCnt = 0;
+
+        try
+        {
+            connection.start();
+
+            // create an XA JMS session and enlist the corresponding XA resource within a transaction
+            XASession xaSession = connection.createXASession();
+            XAResource xaRes = xaSession.getXAResource();
+
+            startJTATx(xaRes, new DummyXAResource(DummyXAResource.faultType.NONE));
+
+            // consume 2 messages withing a transaction
+            MessageConsumer xaConsumer =  xaSession.createConsumer(queue);
+            msgCnt = consumeMessages(xaConsumer, millis, cnt);
+
+            // roll back the transaction - since we consumed the messages inside a transaction they should still be available
+            endJTATx(true);
+
+            xaConsumer.close();
+            xaSession.close();
+        }
+        finally
+        {
+             connection.close();
+        }
+
+        return msgCnt;
+    }
+
+    public void drainQueue() throws Exception {
+        while (consumeMessages(100, 500) == 100)
+           System.out.println("drained 100 messages");
+    }
+
+    @Test
+    public void testIsJmsWorking() throws Exception {
+        XAConnection connection = xacf.createXAConnection();
+
+        drainQueue();
+
+        try
+        {
+            connection.start();
+
+            produceMessages(connection, "hello", "world");
+
+            // create an XA JMS session and enlist the corresponding XA resource within a transaction
+            XASession xaSession = connection.createXASession();
+            XAResource xaRes = xaSession.getXAResource();
+
+            startJTATx(xaRes, new DummyXAResource(DummyXAResource.faultType.NONE));
+
+            // consume the 2 messages within a transaction
+            MessageConsumer xaConsumer =  xaSession.createConsumer(queue);
+
+            if (consumeMessages(xaConsumer, 1000, 2) != 2)
+                throw new Exception("missing messages");
+
+            // roll back the transaction - since we consumed the messages inside a transaction they should still be available
+            endJTATx(false);
+
+            // now have another go at consuming the 2 messages but this time commit
+            startJTATx(xaRes, new DummyXAResource(DummyXAResource.faultType.NONE));
+            if (consumeMessages(xaConsumer, 1000, 2) != 2)
+                throw new Exception("missing messages");
+            // commit the message consumption
+            endJTATx(true);
+
+            // since the work was committed we expect there to be no more messages available
+            if (consumeMessages(xaConsumer, 1000, 1) != 0)
+                throw new Exception("additional messages");
+
+            xaConsumer.close();
+            xaSession.close();
+        }
+        finally
+        {
+             connection.close();
+        }
+    }
+
+
+
+
+    @Test
+    public void testXASendWithoutError() throws Exception {
+        drainQueue();
+        produceMessages(DummyXAResource.faultType.NONE, "hello", "world");
+    }
+
+    @Test
+    public void testXARecvWithoutError() throws Exception {
+        int cnt = consumeMessages(2, 500);
+        Assert.assertEquals("Expected 2 messages but received " + cnt, 2, cnt);
+    }
+
+    @Test
+    public void testXAWithErrorPart1() throws Exception {
+        // drain the queue before producing messages
+        drainQueue();
+
+        produceMessages(DummyXAResource.faultType.HALT, "hello", "world");
+        Assert.fail("The commit request should have halted the VM");
+    }
+
+    @Test
+    public void testXAWithErrorPart2() throws Exception {
+        runRecoveryScan();
+        int cnt = consumeMessages(2, 500);
+        Assert.assertEquals("Expected 2 messages but received " + cnt, 2, cnt);
+
+        System.out.println("Message Count after running recovery: " + cnt);
+    }
+}

Added: labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/RecoverySetup.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/RecoverySetup.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/recovery/RecoverySetup.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,35 @@
+package org.jboss.narayana.examples.recovery;
+
+import com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean;
+import com.arjuna.ats.arjuna.common.RecoveryEnvironmentBean;
+import com.arjuna.ats.arjuna.recovery.RecoveryManager;
+import com.arjuna.common.internal.util.propertyservice.BeanPopulator;
+import junit.framework.Assert;
+import org.jboss.narayana.examples.util.DummyXAResource;
+import org.jboss.narayana.examples.util.Util;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.transaction.*;
+
+public class RecoverySetup {
+    protected static RecoveryManager recoveryManager;
+
+//    @BeforeClass
+    public static void startRecovery() {
+        BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class).setObjectStoreDir(Util.recoveryStoreDir);
+        RecoveryManager.delayRecoveryManagerThread() ;
+        BeanPopulator.getDefaultInstance(RecoveryEnvironmentBean.class).setRecoveryBackoffPeriod(1);
+        recoveryManager = RecoveryManager.manager();
+    }
+
+//    @AfterClass
+    public static void stopRecovery() {
+        recoveryManager.terminate();
+    }
+
+    protected void runRecoveryScan() {
+        recoveryManager.scan();
+    }
+}

Added: labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/DummyXAResource.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/DummyXAResource.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/DummyXAResource.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,105 @@
+package org.jboss.narayana.examples.util;
+
+
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import java.io.Serializable;
+
+public class DummyXAResource implements XAResource, Serializable {
+    static final long serialVersionUID = 1;
+
+    public enum faultType {HALT, EX, NONE}
+
+    private transient faultType fault = faultType.NONE;
+
+    private static int commitRequests = 0;
+
+    private Xid[] recoveryXids;
+
+    public boolean startCalled;
+    public boolean endCalled;
+    public boolean prepareCalled;
+    public boolean commitCalled;
+    public boolean rollbackCalled;
+    public boolean forgetCalled;
+    public boolean recoverCalled;
+
+    public DummyXAResource()
+    {
+        this(faultType.NONE);
+    }
+
+    public DummyXAResource(faultType fault)
+    {
+        this.fault = fault;
+    }
+
+    public void commit(final Xid xid, final boolean arg1) throws XAException
+    {
+        System.out.println("DummyXAResource commit() called, fault: " + fault + " xid: " + xid);
+        commitCalled = true;
+        commitRequests += 1;
+
+        if (fault != null) {
+            if (fault.equals(faultType.EX)) {
+                throw new XAException(XAException.XA_RBTRANSIENT);
+            } else if (fault.equals(faultType.HALT)) {
+                recoveryXids = new Xid[1];
+                recoveryXids[0] = xid;
+                Runtime.getRuntime().halt(1);
+            }
+        }
+    }
+
+    public void end(final Xid xid, final int arg1) throws XAException
+    {
+        endCalled = true;
+    }
+
+    public void forget(final Xid xid) throws XAException
+    {
+        forgetCalled = true;
+    }
+
+    public int getTransactionTimeout() throws XAException
+    {
+        return 0;
+    }
+    public boolean isSameRM(final XAResource arg0) throws XAException
+    {
+        return this.equals(arg0);
+    }
+
+    public int prepare(final Xid xid) throws XAException
+    {
+        prepareCalled = true;
+        return XAResource.XA_OK;
+    }
+
+    public Xid[] recover(final int arg0) throws XAException
+    {
+        recoverCalled = true;
+        return recoveryXids;
+    }
+
+    public void rollback(final Xid xid) throws XAException
+    {
+        rollbackCalled = true;
+    }
+
+    public void start(final Xid xid, final int arg1) throws XAException
+    {
+        startCalled = true;
+    }
+
+    public boolean setTransactionTimeout(final int arg0) throws XAException
+    {
+        return false;
+    }
+
+
+    public static int getCommitRequests() {
+        return commitRequests;
+    }
+}

Added: labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/DummyXid.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/DummyXid.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/DummyXid.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.  See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package org.jboss.narayana.examples.util;
+
+import javax.transaction.xa.Xid;
+
+import org.hornetq.utils.Base64;
+
+/**
+ * @author <a href="mailto:andy.taylor at jboss.org">Andy Taylor</a>
+ */
+public class DummyXid implements Xid
+{
+   private static final long serialVersionUID = 407053232840068514L;
+
+   private final byte[] branchQualifier;
+
+   private final int formatId;
+
+   private final byte[] globalTransactionId;
+
+   private int hash;
+
+   private boolean hashCalculated;
+
+   // Static --------------------------------------------------------
+
+   public static String toBase64String(final Xid xid)
+   {
+      return Base64.encodeBytes(DummyXid.toByteArray(xid));
+   }
+
+   private static byte[] toByteArray(final Xid xid)
+   {
+      byte[] branchQualifier = xid.getBranchQualifier();
+      byte[] globalTransactionId = xid.getGlobalTransactionId();
+      int formatId = xid.getFormatId();
+
+      byte[] hashBytes = new byte[branchQualifier.length + globalTransactionId.length + 4];
+      System.arraycopy(branchQualifier, 0, hashBytes, 0, branchQualifier.length);
+      System.arraycopy(globalTransactionId, 0, hashBytes, branchQualifier.length, globalTransactionId.length);
+      byte[] intBytes = new byte[4];
+      for (int i = 0; i < 4; i++)
+      {
+         intBytes[i] = (byte)((formatId >> i * 8) % 0xFF);
+      }
+      System.arraycopy(intBytes, 0, hashBytes, branchQualifier.length + globalTransactionId.length, 4);
+      return hashBytes;
+   }
+
+   // Constructors --------------------------------------------------
+
+   /**
+    * Standard constructor
+    * @param branchQualifier
+    * @param formatId
+    * @param globalTransactionId
+    */
+   public DummyXid(final byte[] branchQualifier, final int formatId, final byte[] globalTransactionId)
+   {
+      this.branchQualifier = branchQualifier;
+      this.formatId = formatId;
+      this.globalTransactionId = globalTransactionId;
+   }
+
+   /**
+    * Copy constructor
+    * @param other
+    */
+   public DummyXid(final Xid other)
+   {
+      branchQualifier = copyBytes(other.getBranchQualifier());
+      formatId = other.getFormatId();
+      globalTransactionId = copyBytes(other.getGlobalTransactionId());
+   }
+
+   // Xid implementation ------------------------------------------------------------------
+
+   public byte[] getBranchQualifier()
+   {
+      return branchQualifier;
+   }
+
+   public int getFormatId()
+   {
+      return formatId;
+   }
+
+   public byte[] getGlobalTransactionId()
+   {
+      return globalTransactionId;
+   }
+
+   // Public -------------------------------------------------------------------------------
+
+   @Override
+   public int hashCode()
+   {
+      if (!hashCalculated)
+      {
+         calcHash();
+      }
+      return hash;
+   }
+
+   @Override
+   public boolean equals(final Object other)
+   {
+      if (this == other)
+      {
+         return true;
+      }
+      if (!(other instanceof Xid))
+      {
+         return false;
+      }
+      Xid xother = (Xid)other;
+      if (xother.getFormatId() != formatId)
+      {
+         return false;
+      }
+      if (xother.getBranchQualifier().length != branchQualifier.length)
+      {
+         return false;
+      }
+      if (xother.getGlobalTransactionId().length != globalTransactionId.length)
+      {
+         return false;
+      }
+      for (int i = 0; i < branchQualifier.length; i++)
+      {
+         byte[] otherBQ = xother.getBranchQualifier();
+         if (branchQualifier[i] != otherBQ[i])
+         {
+            return false;
+         }
+      }
+      for (int i = 0; i < globalTransactionId.length; i++)
+      {
+         byte[] otherGtx = xother.getGlobalTransactionId();
+         if (globalTransactionId[i] != otherGtx[i])
+         {
+            return false;
+         }
+      }
+      return true;
+   }
+
+   @Override
+   public String toString()
+   {
+      return "XidImpl (" + System.identityHashCode(this) +
+             " bq:" +
+             stringRep(branchQualifier) +
+             " formatID:" +
+             formatId +
+             " gtxid:" +
+             stringRep(globalTransactionId);
+   }
+
+   // Private -------------------------------------------------------------------------------
+
+   private String stringRep(final byte[] bytes)
+   {
+      StringBuffer buff = new StringBuffer();
+      for (int i = 0; i < bytes.length; i++)
+      {
+         byte b = bytes[i];
+
+         buff.append(b);
+
+         if (i != bytes.length - 1)
+         {
+            buff.append('.');
+         }
+      }
+
+      return buff.toString();
+   }
+
+   private void calcHash()
+   {
+      byte[] hashBytes = DummyXid.toByteArray(this);
+      String s = new String(hashBytes);
+      hash = s.hashCode();
+      hashCalculated = true;
+   }
+
+   private byte[] copyBytes(final byte[] other)
+   {
+      byte[] bytes = new byte[other.length];
+
+      System.arraycopy(other, 0, bytes, 0, other.length);
+
+      return bytes;
+   }
+}

Added: labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/Util.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/Util.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/examples/recovery/src/test/java/org/jboss/narayana/examples/util/Util.java	2011-06-22 18:31:53 UTC (rev 37105)
@@ -0,0 +1,84 @@
+package org.jboss.narayana.examples.util;
+
+import com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean;
+import com.arjuna.common.internal.util.propertyservice.BeanPopulator;
+
+import java.io.File;
+
+public class Util {
+    public static final String dataDir = "target/data";
+    public static final String recoveryStoreDir = dataDir + "/recoveryTestStore";
+    public static final String hornetqStoreDir = dataDir + "/hornetq";
+
+    public static void emptyObjectStore() {
+        String objectStoreDirName = BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class).getObjectStoreDir();
+
+        if (objectStoreDirName != null)
+            Util.removeContents(new File(objectStoreDirName));
+    }
+
+    public static int countLogRecords() {
+        String objectStoreDirName = BeanPopulator.getDefaultInstance(ObjectStoreEnvironmentBean.class).getObjectStoreDir();
+
+        if (objectStoreDirName != null) {
+            File osDir = new File(objectStoreDirName);
+
+            if (osDir.exists())
+                return Util.countLogRecords(osDir, 0);
+        }
+
+        return 0;
+    }
+
+    public static int countLogRecords(File directory, int count)
+    {
+        if ((directory != null) &&
+                directory.isDirectory() &&
+                (!directory.getName().equals("")) &&
+                (!directory.getName().equals("/")) &&
+                (!directory.getName().equals("\\")) &&
+                (!directory.getName().equals(".")) &&
+                (!directory.getName().equals("..")))
+        {
+            File[] contents = directory.listFiles();
+
+            for (File f : contents) {
+                if (f.isDirectory()) {
+                    count += countLogRecords(f, count);
+                } else {
+                    count += 1;
+                }
+            }
+        }
+
+        return count;
+    }
+
+
+    public static void removeContents(File directory)
+    {
+        if ((directory != null) &&
+                directory.isDirectory() &&
+                (!directory.getName().equals("")) &&
+                (!directory.getName().equals("/")) &&
+                (!directory.getName().equals("\\")) &&
+                (!directory.getName().equals(".")) &&
+                (!directory.getName().equals("..")))
+        {
+            File[] contents = directory.listFiles();
+
+            for (File f : contents) {
+                if (f.isDirectory()) {
+                    removeContents(f);
+
+                    f.delete();
+                } else {
+                    f.delete();
+                }
+            }
+        }
+
+        if (directory != null)
+            directory.delete();
+    }
+}



More information about the jboss-svn-commits mailing list