Author: covener
Date: Thu Jul 22 20:06:49 2010
New Revision: 966831
URL: http://svn.apache.org/viewvc?rev=966831&view=rev
Log:
OWB-406 OWB-416 OWB-417
rework the tracking of unremoved dependent stateful session beans and
removal of un-removed SFSB during Contextual.destroy()
Modified:
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/component/BaseEjbBean.java
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/proxy/EjbBeanProxyHandler.java
Modified:
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/component/BaseEjbBean.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/component/BaseEjbBean.java?rev=966831&r1=966830&r2=966831&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/component/BaseEjbBean.java
(original)
+++
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/component/BaseEjbBean.java
Thu Jul 22 20:06:49 2010
@@ -20,7 +20,10 @@ package org.apache.webbeans.ejb.common.c
import java.lang.reflect.Method;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.enterprise.context.Dependent;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.SessionBeanType;
@@ -42,9 +45,9 @@ public abstract class BaseEjbBean<T> ext
/**Injected reference local interface type*/
protected Class<?> iface = null;
- /** Has the stateful instance already been removed by a business method
invocation */
- protected boolean removedStatefulInstance = false;
-
+ /** Map of proxy instances to the dependent SFSB they've acquired but not
yet removed */
+ private Map<Object, Object> dependentSFSBToBeRemoved = new
ConcurrentHashMap<Object, Object>();
+
/**
* Creates a new instance of the session bean.
* @param ejbClassType ebj class type
@@ -72,16 +75,6 @@ public abstract class BaseEjbBean<T> ext
}
/**
- * Sets remove flag.
- * @param remove flag
- */
- public void setRemovedStatefulInstance(boolean remove)
- {
- this.removedStatefulInstance = remove;
- }
-
-
- /**
* {...@inheritdoc}
*/
@Override
@@ -90,8 +83,6 @@ public abstract class BaseEjbBean<T> ext
//No-operations
}
-
-
/* (non-Javadoc)
* @see org.apache.webbeans.component.AbstractBean#isPassivationCapable()
*/
@@ -140,17 +131,32 @@ public abstract class BaseEjbBean<T> ext
@Override
protected void destroyComponentInstance(T instance, CreationalContext<T>
creational)
{
- if(!removedStatefulInstance &&
getEjbType().equals(SessionBeanType.STATEFUL))
+ if ((this.getScope() == Dependent.class) &&
(getEjbType().equals(SessionBeanType.STATEFUL)))
{
- //Call remove method
- List<Method> methods = getRemoveMethods();
- for(Method method : methods)
+ try
+ {
+ Object ejbInstance = getDependentSFSBForProxy(instance);
+ if (ejbInstance != null)
+ {
+ List<Method> methods = getRemoveMethods();
+ if (methods.size() > 0)
+ {
+ // FIXME: This needs to call an API from the EJB
+ // container to remove the EJB instance directly, not
+ // via a remove method
+ // For now, just call 1 remove method directly on the
+ // EJB
+ ClassUtil.callInstanceMethod(methods.get(0),
ejbInstance, ClassUtil.OBJECT_EMPTY);
+ }
+ }
+ }
+ finally
{
- ClassUtil.callInstanceMethod(method, instance,
ClassUtil.OBJECT_EMPTY);
+ removeDependentSFSB(instance);
}
- }
+ }
}
-
+
/**
* Sets session bean type.
* @param type session bean type
@@ -196,5 +202,36 @@ public abstract class BaseEjbBean<T> ext
{
return this.ejbType;
}
+
+ /**
+ * Keep track of which proxies have gotten EJB objects out of a context
+ * @param dependentSFSB The dependent SFSB acquired from the EJB container
+ * @param proxy The OWB proxy instance whose method handler acquired the
dependnet SFSB
+ */
+ public void addDependentSFSB(Object dependentSFSB, Object proxy)
+ {
+ dependentSFSBToBeRemoved.put(proxy, dependentSFSB);
+ }
+
+ /**
+ * Call after observing an @Remove method on an EJB instance
+ * @param proxy the proxy instance the dependent SFSB is associated with
+ */
+ public void removeDependentSFSB(Object proxy)
+ {
+ dependentSFSBToBeRemoved.remove(proxy);
+ }
+
+ /**
+ *
+ * @param proxy an instance of our own proxy
+ * @return the underlying EJB instance associated with the proxy
+ */
+ public Object getDependentSFSBForProxy(Object proxy)
+ {
+ return dependentSFSBToBeRemoved.get(proxy);
+ }
+
+
}
\ No newline at end of file
Modified:
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/proxy/EjbBeanProxyHandler.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/proxy/EjbBeanProxyHandler.java?rev=966831&r1=966830&r2=966831&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/proxy/EjbBeanProxyHandler.java
(original)
+++
openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/proxy/EjbBeanProxyHandler.java
Thu Jul 22 20:06:49 2010
@@ -58,7 +58,7 @@ public class EjbBeanProxyHandler impleme
/**Proxy ejb bean instance*/
private BaseEjbBean<?> ejbBean;
- private Object dependentEjb;
+ private Object dependentEJB;
private boolean isDependent = false;
/**Creational Context*/
@@ -84,7 +84,7 @@ public class EjbBeanProxyHandler impleme
if (ejbBean.getScope().equals(Dependent.class))
{
isDependent = true;
- dependentEjb = null;
+ dependentEJB = null;
}
}
@@ -92,7 +92,7 @@ public class EjbBeanProxyHandler impleme
* {...@inheritdoc}
*/
@Override
- public Object invoke(Object instance, Method method, Method proceed,
Object[] arguments) throws Exception
+ public Object invoke(Object proxyInstance, Method method, Method proceed,
Object[] arguments) throws Exception
{
Object result = null;
@@ -107,7 +107,7 @@ public class EjbBeanProxyHandler impleme
SecurityUtil.doPrivilegedSetAccessible(method, true);
try
{
- return proceed.invoke(instance, arguments);
+ return proceed.invoke(proxyInstance, arguments);
}
finally
@@ -119,40 +119,60 @@ public class EjbBeanProxyHandler impleme
try
{
Object webbeansInstance = null;
-
- //Check ejb remove method
- if(this.ejbBean.getEjbType().equals(SessionBeanType.STATEFUL))
- {
- if(checkEjbRemoveMethod(method))
- {
- this.ejbBean.setRemovedStatefulInstance(true);
- }
- }
-
- //Set Ejb bean on thread local
+
+ // Set Ejb bean on thread local
OpenWebBeansEjbInterceptor.setThreadLocal(this.ejbBean,
getContextualCreationalContext());
- //Context of the bean
+ // Context of the bean
Context webbeansContext =
BeanManagerImpl.getManager().getContext(this.ejbBean.getScope());
-
- if (isDependent && this.dependentEjb != null)
+
+ // Don't go into a _dependent_ context on subsequent method calls
in
+ // this proxy!
+ if (isDependent && this.dependentEJB != null)
{
- webbeansInstance = this.dependentEjb;
+ webbeansInstance = this.dependentEJB;
}
- else
+ else
{
- // try looking in the context without
getContextualCreationalContext() first
+ // try looking in the context without
+ // getContextualCreationalContext() first
webbeansInstance = webbeansContext.get(this.ejbBean);
if (webbeansInstance == null)
{
- webbeansInstance =
webbeansContext.get((Contextual<Object>)this.ejbBean,
getContextualCreationalContext());
+ webbeansInstance =
webbeansContext.get((Contextual<Object>) this.ejbBean,
getContextualCreationalContext());
}
- if (isDependent)
+
+ // We just got a new dependent EJB, save it in this the
+ // method handler.
+ if (isDependent && webbeansInstance != null)
{
- this.dependentEjb = webbeansInstance;
+ this.dependentEJB = webbeansInstance;
+
+ if
(this.ejbBean.getEjbType().equals(SessionBeanType.STATEFUL))
+ {
+ // It's an SFSB, so we need to track when it's removed
+ this.ejbBean.addDependentSFSB(webbeansInstance,
proxyInstance);
+ }
}
}
+ //Check ejb remove method for dependent SFSB (
+ if (this.ejbBean.isDependent() &&
this.ejbBean.getEjbType().equals(SessionBeanType.STATEFUL))
+ {
+ if (checkEjbRemoveMethod(method))
+ {
+ // Stop tracking the EJB associated with this proxy
+ this.ejbBean.removeDependentSFSB(proxyInstance);
+
+ /*
+ * Keep the local reference to the dependent SFSB. If the
+ * user calls a contextual EJB with a removed EJB
associated
+ * with it we should let the EJB container complain, not
+ * give them a new EJB under the covers.
+ */
+ }
+ }
+
//Call actual method on proxy
//Actually it is called from OWB Proxy --> EJB Proxy --> Actual
Bean Instance
boolean access = method.isAccessible();