A Patch for JBAS-1509
h2-matsuno Feb 21, 2006 9:14 AMI made a patch for JBAS-1509 to JBoss3.2.7.
http://jira.jboss.com/jira/browse/JBAS-1509
It was already backport to JBoss3.2.8, I know,
but I need this new feature on 3.2.7.
The patch is as follows. This is a diff between 3.2.7 and 3.2.8RC1.
It works well in our system.
Use at your own risk, and I hope this has been helpful.
diff -ur jboss-3.2.7-src/server/src/main/org/jboss/ejb/plugins/TxInterceptorCMT.java jboss-3.2.8RC1-src/server/src/main/org/jboss/ejb/plugins/TxInterceptorCMT.java
--- jboss-3.2.7-src/server/src/main/org/jboss/ejb/plugins/TxInterceptorCMT.java 2004-10-19 00:40:47.000000000 +0900
+++ jboss-3.2.8RC1-src/server/src/main/org/jboss/ejb/plugins/TxInterceptorCMT.java 2005-12-07 11:23:18.000000000 +0900
@@ -1,8 +1,23 @@
 /*
- * JBoss, the OpenSource J2EE webOS
+ * 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.
 *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
+ * 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.ejb.plugins;
@@ -32,7 +47,6 @@
 import javax.transaction.TransactionRolledbackException;
 import java.lang.reflect.Method;
 import java.rmi.RemoteException;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Random;
 import java.util.Iterator;
@@ -46,7 +60,7 @@
 * @author <a href="mailto:sebastien.alborini@m4x.org">Sebastien Alborini</a>
 * @author <a href="mailto:akkerman@cs.nyu.edu">Anatoly Akkerman</a>
 * @author <a href="mailto:osh@sparre.dk">Ole Husgaard</a>
- * @version $Revision: 1.27.2.16 $
+ * @version $Revision: 1.27.2.19 $
 */
 public class TxInterceptorCMT extends AbstractTxInterceptor implements XmlLoadable
 {
@@ -56,6 +70,12 @@
 /** A cache mapping methods to transaction attributes. */
 private ConcurrentReaderHashMap methodTx = new ConcurrentReaderHashMap();
+ /**
+ * Whether an exception should be thrown if the transaction is not
+ * active, even though the application doesn't throw an exception
+ */
+ private boolean exceptionRollback = true;
+
 // Static --------------------------------------------------------
 // Constructors --------------------------------------------------
@@ -64,6 +84,15 @@
 // Interceptor implementation --------------------------------------
+ public void create() throws Exception
+ {
+ super.create();
+ BeanMetaData bmd = getContainer().getBeanMetaData();
+ exceptionRollback = bmd.getExceptionRollback();
+ if (exceptionRollback == false)
+ exceptionRollback = bmd.getApplicationMetaData().getExceptionRollback();
+ }
+
 public static int MAX_RETRIES = 5;
 public static Random random = new Random();
@@ -291,6 +320,7 @@
 case MetaData.TX_REQUIRED:
 {
 int oldTimeout = 0;
+ Transaction theTransaction = oldTransaction;
 if (oldTransaction == null)
 { // No tx running
 // Create tx
@@ -303,6 +333,7 @@
 // Let the method invocation know
 invocation.setTransaction(newTransaction);
+ theTransaction = newTransaction;
 }
 else
 {
@@ -314,7 +345,9 @@
 // Continue invocation
 try
 {
- return invokeNext(invocation, oldTransaction != null);
+ Object result = invokeNext(invocation, oldTransaction != null);
+ checkTransactionStatus(theTransaction, type);
+ return result;
 }
 finally
 {
@@ -340,7 +373,10 @@
 try
 {
- return invokeNext(invocation, oldTransaction != null);
+ Object result = invokeNext(invocation, oldTransaction != null);
+ if (oldTransaction != null)
+ checkTransactionStatus(oldTransaction, type);
+ return result;
 }
 finally
 {
@@ -363,7 +399,9 @@
 // Continue invocation
 try
 {
- return invokeNext(invocation, false);
+ Object result = invokeNext(invocation, false);
+ checkTransactionStatus(newTransaction, type);
+ return result;
 }
 finally
 {
@@ -392,8 +430,11 @@
 tm.resume(oldTransaction);
 try
 {
- return invokeNext(invocation, true);
- } finally
+ Object result = invokeNext(invocation, true);
+ checkTransactionStatus(oldTransaction, type);
+ return result;
+ }
+ finally
 {
 tm.suspend();
 }
@@ -553,6 +594,40 @@
 }
 }
+ /**
+ * The application has not thrown an exception, but...
+ * When exception-on-rollback is true,
+ * check whether the transaction is not active.
+ * If it did not throw an exception anyway.
+ *
+ * @param tx the transaction
+ * @param type the invocation type
+ * @throws TransactionRolledbackException if transaction is no longer active
+ */
+ protected void checkTransactionStatus(Transaction tx, InvocationType type)
+ throws TransactionRolledbackException
+ {
+ if (exceptionRollback)
+ {
+ if (log.isTraceEnabled())
+ log.trace("No exception from ejb, checking transaction status: " + tx);
+ int status = Status.STATUS_UNKNOWN;
+ try
+ {
+ status = tx.getStatus();
+ }
+ catch (Throwable t)
+ {
+ log.debug("Ignored error trying to retrieve transaction status", t);
+ }
+ if (status != Status.STATUS_ACTIVE)
+ {
+ Exception e = new Exception("Transaction cannot be committed (probably transaction timeout): " + tx);
+ throwJBossException(e, type);
+ }
+ }
+ }
+
 // Inner classes -------------------------------------------------
 // Monitorable implementation ------------------------------------
diff -ur jboss-3.2.7-src/server/src/main/org/jboss/metadata/ApplicationMetaData.java jboss-3.2.8RC1-src/server/src/main/org/jboss/metadata/ApplicationMetaData.java
--- jboss-3.2.7-src/server/src/main/org/jboss/metadata/ApplicationMetaData.java 2003-05-03 08:40:33.000000000 +0900
+++ jboss-3.2.8RC1-src/server/src/main/org/jboss/metadata/ApplicationMetaData.java 2005-12-07 11:23:18.000000000 +0900
@@ -1,10 +1,24 @@
 /*
- * JBoss, the OpenSource J2EE webOS
+ * 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.
 *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
+ * 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.metadata;
 import java.net.URL;
@@ -27,7 +41,7 @@
 * @author <a href="mailto:Scott.Stark@jboss.org">Scott Stark</a>
 * @author <a href="mailto:criege@riege.com">Christian Riege</a>
 *
- * @version $Revision: 1.29.2.3 $
+ * @version $Revision: 1.29.2.5 $
 */
 public class ApplicationMetaData
 extends MetaData
@@ -60,6 +74,8 @@
 /** The unauthenticated-principal value assigned to the application */
 private String unauthenticatedPrincipal;
 private boolean enforceEjbRestrictions;
+ /** Whether to throw an exception on a rollback if there is no exception */
+ private boolean exceptionRollback = false;
 public ApplicationMetaData(URL u)
 {
@@ -187,6 +203,11 @@
 return enforceEjbRestrictions;
 }
+ public boolean getExceptionRollback()
+ {
+ return exceptionRollback;
+ }
+
 /**
 * Import data provided by ejb-jar.xml
 *
@@ -587,6 +608,9 @@
 jmxName = getElementContent(jmxNameElement);
 }
+ // Throw an exception when marked rollback with no exception thrown
+ exceptionRollback = MetaData.getOptionalChildBooleanContent(element, "exception-on-rollback", false);
+
 // Get the security domain name
 Element securityDomainElement = getOptionalChild(element,
 "security-domain");
diff -ur jboss-3.2.7-src/server/src/main/org/jboss/metadata/BeanMetaData.java jboss-3.2.8RC1-src/server/src/main/org/jboss/metadata/BeanMetaData.java
--- jboss-3.2.7-src/server/src/main/org/jboss/metadata/BeanMetaData.java 2005-01-27 16:12:17.000000000 +0900
+++ jboss-3.2.8RC1-src/server/src/main/org/jboss/metadata/BeanMetaData.java 2005-12-07 11:23:18.000000000 +0900
@@ -1,10 +1,24 @@
 /*
- * JBoss, the OpenSource J2EE webOS
+ * 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.
 *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
+ * 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.metadata;
 import java.lang.reflect.Method;
@@ -38,7 +52,7 @@
 * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
 * @author <a href="mailto:criege@riege.com">Christian Riege</a>
 *
- * @version $Revision: 1.41.2.15 $
+ * @version $Revision: 1.41.2.17 $
 */
 public abstract class BeanMetaData
 extends MetaData
@@ -130,6 +144,9 @@
 /** Any object names for services the bean depends on */
 private Collection depends = new LinkedList();
+ /** Whether to throw an exception on a rollback if there is no exception */
+ private boolean exceptionRollback = false;
+
 // Static --------------------------------------------------------
 // Constructors --------------------------------------------------
@@ -586,6 +603,11 @@
 return callByValue;
 }
+ public boolean getExceptionRollback()
+ {
+ return exceptionRollback;
+ }
+
 public void importEjbJarXml(Element element)
 throws DeploymentException
 {
@@ -722,6 +744,9 @@
 securityProxy = getElementContent(getOptionalChild(element,
 "security-proxy"), securityProxy);
+ // Throw an exception when marked rollback with no exception thrown
+ exceptionRollback = MetaData.getOptionalChildBooleanContent(element, "exception-on-rollback", false);
+
 // update the resource references (optional)
 Iterator iterator = getChildrenByTagName(element, "resource-ref");
 while (iterator.hasNext()) {
diff -ur jboss-3.2.7-src/server/src/main/org/jboss/metadata/MetaData.java jboss-3.2.8RC1-src/server/src/main/org/jboss/metadata/MetaData.java
--- jboss-3.2.7-src/server/src/main/org/jboss/metadata/MetaData.java 2004-08-12 01:10:58.000000000 +0900
+++ jboss-3.2.8RC1-src/server/src/main/org/jboss/metadata/MetaData.java 2005-12-07 11:23:18.000000000 +0900
@@ -1,8 +1,23 @@
 /*
- * JBoss, the OpenSource J2EE webOS
+ * 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.
 *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
+ * 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.metadata;
@@ -21,7 +36,7 @@
 * An abstract base class for metadata containers.
 *
 * @author <a href="mailto:sebastien.alborini@m4x.org">Sebastien Alborini</a>
- * @version $Revision: 1.21.2.7 $
+ * @version $Revision: 1.21.2.9 $
 */
 public abstract class MetaData
 implements Cloneable, XmlLoadable
@@ -276,6 +291,21 @@
 return false;
 }
+ public static boolean getOptionalChildBooleanContent(Element element,
+ String name, boolean defaultValue)
+ throws DeploymentException
+ {
+ Element child = getOptionalChild(element, name);
+ boolean flag = defaultValue;
+ if(child != null)
+ {
+ String value = getElementContent(child).toLowerCase();
+ flag = value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes");
+ }
+
+ return flag;
+ }
+
 // Constructors --------------------------------------------------
 // Public --------------------------------------------------------
diff -ur jboss-3.2.7-src/server/src/resources/org/jboss/metadata/jboss_3_2.dtd jboss-3.2.8RC1-src/server/src/resources/org/jboss/metadata/jboss_3_2.dtd
--- jboss-3.2.7-src/server/src/resources/org/jboss/metadata/jboss_3_2.dtd 2005-01-28 15:45:26.000000000 +0900
+++ jboss-3.2.8RC1-src/server/src/resources/org/jboss/metadata/jboss_3_2.dtd 2005-12-07 11:23:18.000000000 +0900
@@ -7,8 +7,8 @@
 "-//JBoss//DTD JBOSS 3.2//EN"
 "http://www.jboss.org/j2ee/dtd/jboss_3_2.dtd">
-$Id: jboss_3_2.dtd,v 1.1.2.29 2005/01/28 05:48:31 starksm Exp $
-$Revision: 1.1.2.29 $
+$Id: jboss_3_2.dtd,v 1.1.2.34 2005/12/07 02:23:18 adrian Exp $
+$Revision: 1.1.2.34 $
 Overview of the architecture of jboss.xml
@@ -24,8 +24,8 @@
 <ejb-name />
 <jndi-name />
 <local-jndi-name />
- <read-only>
 <call-by-value/>
+ <read-only>
 <configuration-name>
 <security-proxy>
 <ejb-ref>
@@ -91,8 +91,12 @@
 <container-configuration>
 <container-name />
+ <call-logging />
+ <invoker-proxy-binding-name />
+ <sync-on-commit-only />
+ <insert-after-ejb-post-create />
+ <call-ejb-store-on-clean />
 <container-interceptors />
- <client-interceptors />
 <instance-pool />
 <instance-cache />
 <persistence-manager />
@@ -102,7 +106,9 @@
 <container-pool-conf />
 <commit-option />
 <optiond-refresh-rate />
- <security-domain/>
+ <security-domain />
+ <cluster-config />
+ <depends />
 </container-configuration>
 </container-configurations>
@@ -123,7 +129,7 @@
 -->
 <!ELEMENT jboss (loader-repository?, jmx-name?, enforce-ejb-restrictions?,
- security-domain?, unauthenticated-principal? , enterprise-beans?,
+ security-domain?, unauthenticated-principal? , exception-on-rollback?, enterprise-beans?,
 resource-managers?, invoker-proxy-bindings?, container-configurations?)>
 <!-- The loader-repository specifies the name of the UnifiedLoaderRepository
@@ -351,7 +357,8 @@
 Used in: enterprise-beans
 -->
 <!ELEMENT entity (ejb-name , jndi-name? , local-jndi-name? , call-by-value?, read-only? ,
- configuration-name? , invoker-bindings?, security-proxy? , ejb-ref* , ejb-local-ref* , resource-ref* ,
+ exception-on-rollback?, configuration-name? , invoker-bindings?, security-proxy? ,
+ ejb-ref* , ejb-local-ref* , resource-ref* ,
 resource-env-ref* , method-attributes? , clustered? , cluster-config?,
 cache-invalidation? , cache-invalidation-config?, depends*)>
@@ -364,8 +371,9 @@
 Used in: enterprise-beans
 -->
-<!ELEMENT session (ejb-name , jndi-name? , local-jndi-name?, call-by-value?, configuration-name?,
- invoker-bindings?, security-proxy? , ejb-ref* , ejb-local-ref* , resource-ref* , resource-env-ref* , clustered? ,
+<!ELEMENT session (ejb-name , jndi-name? , local-jndi-name?, call-by-value?,
+ exception-on-rollback?, configuration-name?, invoker-bindings?, security-proxy? ,
+ ejb-ref* , ejb-local-ref* , resource-ref* , resource-env-ref* , clustered? ,
 cluster-config?, method-attributes?, depends*)>
 <!--
@@ -377,9 +385,9 @@
 Used in: enterprise-beans
 -->
-<!ELEMENT message-driven (ejb-name , destination-jndi-name ,
+<!ELEMENT message-driven (ejb-name , destination-jndi-name , local-jndi-name?,
 mdb-user?, mdb-passwd? , mdb-client-id? , mdb-subscription-id? ,
- configuration-name? , invoker-bindings?,
+ exception-on-rollback?, configuration-name? , invoker-bindings?,
 security-proxy? , ejb-ref* , ejb-local-ref* , resource-ref* , resource-env-ref*, depends*)>
 <!--
@@ -430,6 +438,21 @@
 <!ELEMENT read-only (#PCDATA)>
 <!--
+ Whether to throw an exception if the CMT controlled
+ transaction is no longer active (e.g. marked rollback)
+ but the application has not itself thrown an exception.
+ If the bean specifies false, it uses the
+ jboss/exception-on-rollback config.
+ Defaults to false.
+ It must be one of the following :
+ <exception-on-rollback>true</exception-on-rollback>
+ <exception-on-rollback>false</exception-on-rollback>
+
+ Used in: jboss, session, entity and message-driven
+-->
+<!ELEMENT exception-on-rollback (#PCDATA)>
+
+<!--
 The configuration-name element gives the name of the container
 configuration for this bean. It must match one of the container-name
 tags in the container-configurations section, or one of the standard
@@ -851,7 +874,8 @@
 <!ELEMENT insert-after-ejb-post-create (#PCDATA)>
 <!-- The call-ejb-store-for-clean says whether ejbStore should be called on clean instances
- at synchronization time. By the spec it should be true.
+ at synchronization time. By the spec it should be true. But users wanted it to be false.
+ False is the default, meaning ejbStore is called only on dirty instances.
 -->
 <!ELEMENT call-ejb-store-on-clean (#PCDATA)>
