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);
}
}