Author: dblevins
Date: Thu May 14 05:17:38 2009
New Revision: 774635

URL: http://svn.apache.org/viewvc?rev=774635&view=rev
Log:
Patch from Bharath Ganesh, OPENEJB-976:  Semaphore in StatelessInstanceManager 
not released if EjbTransactionUtil.afterInvoke throws RuntimeException
Thanks, Bharath!

Modified:
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ThreadContext.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/EjbTransactionUtil.java

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ThreadContext.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ThreadContext.java?rev=774635&r1=774634&r2=774635&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ThreadContext.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ThreadContext.java
 Thu May 14 05:17:38 2009
@@ -100,6 +100,12 @@
     private Class invokedInterface;
     private TransactionPolicy transactionPolicy;
 
+    /**
+     * A boolean which keeps track of whether to discard the bean instance 
after the method invocation.
+     * The boolean would be set to true in case of exceptions which mandate 
bean discard.
+     */
+    private boolean discardInstance;
+
     public ThreadContext(CoreDeploymentInfo deploymentInfo, Object primaryKey) 
{
         this(deploymentInfo, primaryKey, null);
     }
@@ -171,4 +177,12 @@
     public <T> T set(Class<T> type, T value) {
         return (T) data.put(type, value);
     }
+
+    public boolean isDiscardInstance() {
+        return discardInstance;
+    }
+
+    public void setDiscardInstance(boolean discardInstance) {
+        this.discardInstance = discardInstance;
+    }
 }

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java?rev=774635&r1=774634&r2=774635&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
 Thu May 14 05:17:38 2009
@@ -30,11 +30,7 @@
 import javax.ejb.EJBObject;
 import javax.interceptor.AroundInvoke;
 
-import org.apache.openejb.ContainerType;
-import org.apache.openejb.DeploymentInfo;
-import org.apache.openejb.InterfaceType;
-import org.apache.openejb.OpenEJBException;
-import org.apache.openejb.ProxyInfo;
+import org.apache.openejb.*;
 import org.apache.openejb.core.CoreDeploymentInfo;
 import org.apache.openejb.core.ExceptionType;
 import org.apache.openejb.core.Operation;
@@ -150,6 +146,7 @@
 
         ThreadContext callContext = new ThreadContext(deployInfo, primKey);
         ThreadContext oldCallContext = ThreadContext.enter(callContext);
+        Object bean = null;
         try {
             boolean authorized = 
getSecurityService().isCallerAuthorized(callMethod, type);
             if (!authorized)
@@ -165,7 +162,7 @@
                 return null;// EJBObject.remove( ) and other EJBObject methods 
are not process by the container
             }
 
-            Object bean = instanceManager.getInstance(callContext);
+            bean = instanceManager.getInstance(callContext);
 
             callContext.setCurrentOperation(Operation.BUSINESS);
             callContext.setCurrentAllowedStates(StatelessContext.getStates());
@@ -175,11 +172,17 @@
             callContext.set(Method.class, runMethod);
             callContext.setInvokedInterface(callInterface);
             Object retValue = _invoke(callMethod, runMethod, args, (Instance) 
bean, callContext, type);
-            instanceManager.poolInstance(callContext, bean);
 
             return retValue;
 
         } finally {
+            if (bean != null) {
+                if (callContext.isDiscardInstance()) {
+                    instanceManager.discardInstance(callContext);
+                } else {
+                    instanceManager.poolInstance(callContext, bean);
+                }
+            }
             ThreadContext.exit(oldCallContext);
         }
     }
@@ -226,17 +229,25 @@
                 // and therefore the instance will be garbage collected and 
destroyed.
                 // In case of StrictPooling flag being set to true we also 
release the semaphore
                // in the discardInstance method of the instanceManager.
-               instanceManager.discardInstance(callContext);
+               callContext.setDiscardInstance(true);
                 handleSystemException(txPolicy, re, callContext);
             } else {
                 /* Application Exception ***********************/
-                instanceManager.poolInstance(callContext, instance);
 
                 handleApplicationException(txPolicy, re, exceptionType == 
ExceptionType.APPLICATION_ROLLBACK);
             }
         } finally {
-
-            afterInvoke(txPolicy, callContext);
+            try {
+                afterInvoke(txPolicy, callContext);
+            } catch (SystemException e) {
+                callContext.setDiscardInstance(true);
+                throw e;
+            } catch (ApplicationException e) {
+                throw e;
+            } catch (RuntimeException e) {
+                callContext.setDiscardInstance(true);
+                throw e;
+            }
         }
 
         return returnValue;

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/EjbTransactionUtil.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/EjbTransactionUtil.java?rev=774635&r1=774634&r2=774635&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/EjbTransactionUtil.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/EjbTransactionUtil.java
 Thu May 14 05:17:38 2009
@@ -87,6 +87,7 @@
                 txPolicy.setRollbackOnly();
                 txPolicy.commit();
             } catch (Exception e) {
+                threadContext.setDiscardInstance(true);
                 logger.error("Error rolling back transaction", e);
             }
 
@@ -96,6 +97,7 @@
                     threadContextTxPolicy.setRollbackOnly();
                     threadContextTxPolicy.commit();
                 } catch (Exception e) {
+                    threadContext.setDiscardInstance(true);
                     logger.error("Error rolling back transaction", e);
                 }
             }


Reply via email to