You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2012/10/06 15:41:07 UTC

svn commit: r1395056 - in /openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb: cdi/CdiEjbBean.java cdi/CdiPlugin.java core/ivm/EjbHomeProxyHandler.java core/stateful/StatefulEjbHomeHandler.java

Author: rmannibucau
Date: Sat Oct  6 13:41:06 2012
New Revision: 1395056

URL: http://svn.apache.org/viewvc?rev=1395056&view=rev
Log:
TOMEE-445 more work to get an OWB proxy in front of our EJB proxies when mandatory to manage scopes

Modified:
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiEjbBean.java
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiPlugin.java
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbHomeProxyHandler.java
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulEjbHomeHandler.java

Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiEjbBean.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiEjbBean.java?rev=1395056&r1=1395055&r2=1395056&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiEjbBean.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiEjbBean.java Sat Oct  6 13:41:06 2012
@@ -19,11 +19,15 @@ package org.apache.openejb.cdi;
 import org.apache.openejb.BeanContext;
 import org.apache.openejb.BeanType;
 import org.apache.openejb.assembler.classic.ProxyInterfaceResolver;
-import org.apache.webbeans.component.AbstractOwbBean;
+import org.apache.webbeans.component.OwbBean;
+import org.apache.webbeans.component.WebBeansType;
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.ejb.common.component.BaseEjbBean;
 
+import javax.ejb.NoSuchEJBException;
 import javax.ejb.Remove;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.Context;
 import javax.enterprise.context.spi.CreationalContext;
 import javax.enterprise.inject.Typed;
 import javax.enterprise.inject.spi.Bean;
@@ -34,12 +38,16 @@ import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 public class CdiEjbBean<T> extends BaseEjbBean<T> {
+    private final Map<Integer, Object> dependentSFSBToBeRemoved = new ConcurrentHashMap<Integer, Object>();
+
     private final BeanContext beanContext;
-    private final ThreadLocal<Class<?>> askedType = new ThreadLocal<Class<?>>();
 
     public CdiEjbBean(BeanContext beanContext, WebBeansContext webBeansContext) {
         this(beanContext, webBeansContext, beanContext.getManagedClass());
@@ -83,18 +91,8 @@ public class CdiEjbBean<T> extends BaseE
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    protected T getInstance(CreationalContext<T> creationalContext) {
-        Type asked = askedType.get();
-        if (asked == null) {
-            askedType.remove();
-            asked = getBeanClass();
-        }
-        return (T) webBeansContext.getBeanManagerImpl().getReference(new RealEjbBean(this), asked, creationalContext);
-    }
-
-    @Override
     protected void afterConstructor(T instance, CreationalContext<T> tCreationalContext) {
+        // no-op
     }
 
 //    @Override
@@ -143,18 +141,42 @@ public class CdiEjbBean<T> extends BaseE
     }
 
     @Override
-    protected void destroyComponentInstance(T instance, CreationalContext<T> creational) {
-
-        if (instance instanceof BeanContext.Removable) {
-            BeanContext.Removable removable = (BeanContext.Removable) instance;
-            removable.$$remove();
+    @SuppressWarnings("unchecked")
+    protected T getInstance(final CreationalContext<T> creationalContext) {
+        final T instance;
+        if (Dependent.class == scopeClass) { // no need to add any layer
+            instance = createEjb(creationalContext);
+        } else {
+            final InstanceBean<T> bean = new InstanceBean<T>(this);
+            if (webBeansContext.getWebBeansUtil().isScopeTypeNormal(scopeClass)) {
+                instance = (T) webBeansContext.getProxyFactory().createNormalScopedBeanProxy(bean, creationalContext);
+            } else {
+                final Context context = webBeansContext.getBeanManagerImpl().getContext(scopeClass);
+                instance = context.get(bean, creationalContext);
+            }
+            bean.setOWBProxy(instance);
         }
+        return instance;
+    }
 
+    @Override
+    protected void destroyComponentInstance(final T instance, final CreationalContext<T> creational) {
+        if (Dependent.class == scopeClass) {
+            destroyStatefulSessionBeanInstance(instance, creational);
+        } else {
+            destroyScopedStateful(instance, creational);
+        }
     }
 
     @Override
-    protected void destroyStatefulSessionBeanInstance(T proxyInstance, Object ejbInstance) {
-        // super.destroyStatefulSessionBeanInstance(proxyInstance, ejbInstance);
+    protected void destroyStatefulSessionBeanInstance(final T proxyInstance, final Object ejbInstance) {
+        if (proxyInstance instanceof BeanContext.Removable) {
+            try {
+                ((BeanContext.Removable) proxyInstance).$$remove();
+            } catch (NoSuchEJBException nsee) {
+                // no-op
+            }
+        }
     }
 
     @Override
@@ -235,164 +257,231 @@ public class CdiEjbBean<T> extends BaseE
         return toReturn;
     }
 
-    public void setAskedType(final Class<?> askedType) {
-        this.askedType.set(askedType);
+    private T createEjb(final CreationalContext<T> creationalContext) {
+        final List<Class> classes = beanContext.getBusinessLocalInterfaces();
+        final CurrentCreationalContext currentCreationalContext = beanContext.get(CurrentCreationalContext.class);
+        final CreationalContext existing = currentCreationalContext.get();
+        currentCreationalContext.set(creationalContext);
+        try {
+            if (classes.size() == 0 && beanContext.isLocalbean()) {
+                final BeanContext.BusinessLocalBeanHome home = beanContext.getBusinessLocalBeanHome();
+                return (T) home.create();
+            } else {
+                final Class<?> mainInterface = classes.get(0);
+                final List<Class> interfaces = ProxyInterfaceResolver.getInterfaces(beanContext.getBeanClass(), mainInterface, classes);
+                final BeanContext.BusinessLocalHome home = beanContext.getBusinessLocalHome(interfaces, mainInterface);
+                return (T) home.create();
+            }
+        } finally {
+            currentCreationalContext.set(existing);
+        }
     }
 
-    public void clearAskedType() {
-        askedType.remove();
+    private void destroyScopedStateful(final T instance, final CreationalContext<T> cc) {
+        instance.hashCode(); // force the instance to be created - otherwise we'll miss @PreDestroy for instance
+
+        Object ejbInstance = dependentSFSBToBeRemoved.remove(System.identityHashCode(instance));
+        if (ejbInstance != null) {
+            destroyStatefulSessionBeanInstance((T) ejbInstance, cc);
+        }
     }
 
-    private static class RealEjbBean<T> extends AbstractOwbBean<T> {
-        private final CdiEjbBean<T> delegate;
+    // does pretty much nothing
+    // used only to get a layer between our EJB proxies and OWB proxies to let them manage the scope
+    private static class InstanceBean<T> implements OwbBean<T> {
+        private final CdiEjbBean<T> bean;
+        private T OWBProxy;
+
+        public InstanceBean(final CdiEjbBean<T> tCdiEjbBean) {
+            bean = tCdiEjbBean;
+        }
+
+        @Override
+        public T createNewInstance(final CreationalContext<T> creationalContext) {
+            return create(creationalContext);
+        }
+
+        @Override
+        public void destroyCreatedInstance(final T instance, final CreationalContext<T> creationalContext) {
+            System.out.println("destroyed " + instance);
+            bean.destroyComponentInstance(instance, creationalContext);
+        }
 
-        public RealEjbBean(final CdiEjbBean<T> cdiEjbBean) {
-            super(cdiEjbBean.getWebBeansType(), cdiEjbBean.getReturnType(), cdiEjbBean.getWebBeansContext());
+        @Override
+        public Set<Type> getTypes() {
+            return bean.getTypes();
+        }
 
-            delegate = cdiEjbBean;
+        @Override
+        public Set<Annotation> getQualifiers() {
+            return bean.getQualifiers();
+        }
 
-            setNullable(cdiEjbBean.isNullable());
-            setSerializable(cdiEjbBean.isSerializable());
-            setEnabled(cdiEjbBean.isEnabled());
-            setName(cdiEjbBean.getName());
-            setSpecializedBean(cdiEjbBean.isSpecializedBean());
+        @Override
+        public Class<? extends Annotation> getScope() {
+            return bean.getScope();
         }
 
         @Override
-        public void setImplScopeType(final Annotation scopeType) {
-            delegate.setImplScopeType(scopeType);
+        public String getName() {
+            return bean.getName();
         }
 
+        @Override
+        public boolean isNullable() {
+            return bean.isNullable();
+        }
 
         @Override
-        public T createNewInstance(final CreationalContext<T> creationalContext) {
-            final List<Class> classes = delegate.beanContext.getBusinessLocalInterfaces();
-            CurrentCreationalContext currentCreationalContext = delegate.beanContext.get(CurrentCreationalContext.class);
-            CreationalContext existing = currentCreationalContext.get();
-            currentCreationalContext.set(creationalContext);
-            try {
-                if (classes.size() == 0 && delegate.beanContext.isLocalbean()) {
-                    BeanContext.BusinessLocalBeanHome home = delegate.beanContext.getBusinessLocalBeanHome();
-                    return (T) home.create();
-                } else {
-                    final Class<?> mainInterface = classes.get(0);
-                    List<Class> interfaces = ProxyInterfaceResolver.getInterfaces(delegate.beanContext.getBeanClass(), mainInterface, classes);
-                    BeanContext.BusinessLocalHome home = delegate.beanContext.getBusinessLocalHome(interfaces, mainInterface);
-                    return (T) home.create();
-                }
-            } finally {
-                currentCreationalContext.set(existing);
+        public Set<InjectionPoint> getInjectionPoints() {
+            return Collections.emptySet();
+        }
+
+        @Override
+        public Class<?> getBeanClass() {
+            return bean.getBeanClass();
+        }
+
+        @Override
+        public Set<Class<? extends Annotation>> getStereotypes() {
+            return bean.getStereotypes();
+        }
+
+        @Override
+        public boolean isAlternative() {
+            return bean.isAlternative();
+        }
+
+        @Override
+        public T create(final CreationalContext<T> creationalContext) {
+            final T instance = bean.createEjb(creationalContext);
+            if (OWBProxy != null && SessionBeanType.STATEFUL.equals(bean.getEjbType())) { // we need to be able to remove OWB proxy to remove (statefuls for instance)
+                bean.dependentSFSBToBeRemoved.put(System.identityHashCode(OWBProxy), instance);
             }
+            return instance;
         }
 
         @Override
-        public void destroyCreatedInstance(final T instance, final CreationalContext<T> creationalContext) {
-            delegate.destroyCreatedInstance(instance, creationalContext);
+        public void destroy(final T instance, final CreationalContext<T> cc) {
+            if (!SessionBeanType.STATEFUL.equals(bean.getEjbType())) {
+                return;
+            }
+
+            bean.destroy(instance, cc);
+        }
+
+        @Override
+        public void setImplScopeType(final Annotation scopeType) {
+            // no-op
+        }
+
+        @Override
+        public WebBeansType getWebBeansType() {
+            return bean.getWebBeansType();
         }
 
         @Override
         public void addQualifier(final Annotation qualifier) {
-            delegate.addQualifier(qualifier);
+            // no-op
+        }
+
+        @Override
+        public boolean isSerializable() {
+            return bean.isSerializable();
         }
 
         @Override
         public void addStereoType(final Annotation stereoType) {
-            delegate.addStereoType(stereoType);
+            // no-op
         }
 
         @Override
         public void addApiType(final Class<?> apiType) {
-            delegate.addApiType(apiType);
+            // no-op
         }
 
         @Override
         public void addInjectionPoint(final InjectionPoint injectionPoint) {
-            delegate.addInjectionPoint(injectionPoint);
+            // no-op
         }
 
         @Override
         public Set<Annotation> getOwbStereotypes() {
-            return delegate.getOwbStereotypes();
+            return bean.getOwbStereotypes();
         }
 
         @Override
-        public List<InjectionPoint> getInjectionPoint(final Member member) {
-            return delegate.getInjectionPoint(member);
-        }
-
-        @Override
-        public String getId() {
-            return delegate.getId();
+        public void setName(final String name) {
+            // no-op
         }
 
         @Override
-        public boolean isPassivationCapable() {
-            return delegate.isPassivationCapable();
+        public List<InjectionPoint> getInjectionPoint(final Member member) {
+            return Collections.emptyList();
         }
 
         @Override
-        public boolean isDependent() {
-            return delegate.isDependent();
+        public Class<T> getReturnType() {
+            return bean.getReturnType();
         }
 
         @Override
-        public void validatePassivationDependencies() {
-            delegate.validatePassivationDependencies();
+        public void setSerializable(final boolean serializable) {
+            // no-op
         }
 
         @Override
-        public WebBeansContext getWebBeansContext() {
-            return delegate.getWebBeansContext();
+        public void setNullable(final boolean nullable) {
+            // no-op
         }
 
         @Override
-        public Set<Type> getTypes() {
-            return delegate.getTypes();
+        public void setSpecializedBean(boolean specialized) {
+            // no-op
         }
 
         @Override
-        public Set<Annotation> getQualifiers() {
-            return delegate.getQualifiers();
+        public boolean isSpecializedBean() {
+            return bean.isSpecializedBean();
         }
 
         @Override
-        public Class<? extends Annotation> getScope() {
-            return delegate.getScope();
+        public void setEnabled(boolean enabled) {
+            // no-op
         }
 
         @Override
-        public String getName() {
-            return delegate.getName();
+        public boolean isEnabled() {
+            return bean.isEnabled();
         }
 
         @Override
-        public Set<InjectionPoint> getInjectionPoints() {
-            return delegate.getInjectionPoints();
+        public String getId() {
+            return bean.getId();
         }
 
         @Override
-        public Class<?> getBeanClass() {
-            return delegate.getBeanClass();
+        public boolean isPassivationCapable() {
+            return bean.isPassivationCapable();
         }
 
         @Override
-        public Set<Class<? extends Annotation>> getStereotypes() {
-            return delegate.getStereotypes();
+        public boolean isDependent() {
+            return bean.isDependent();
         }
 
         @Override
-        public boolean isAlternative() {
-            return delegate.isAlternative();
+        public void validatePassivationDependencies() {
+            bean.validatePassivationDependencies();
         }
 
         @Override
-        protected T createInstance(final CreationalContext<T> creationalContext) {
-            return createNewInstance(creationalContext);
+        public WebBeansContext getWebBeansContext() {
+            return bean.getWebBeansContext();
         }
 
-        @Override
-        protected void destroyInstance(final T instance, final CreationalContext<T> creationalContext) {
-            delegate.destroyCreatedInstance(instance, creationalContext);
+        public void setOWBProxy(final T OWBProxy) {
+            this.OWBProxy = OWBProxy;
         }
     }
 }

Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiPlugin.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiPlugin.java?rev=1395056&r1=1395055&r2=1395056&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiPlugin.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiPlugin.java Sat Oct  6 13:41:06 2012
@@ -16,16 +16,6 @@
  */
 package org.apache.openejb.cdi;
 
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.Set;
-import java.util.WeakHashMap;
-import javax.ejb.Stateful;
-import javax.enterprise.context.spi.Context;
-import javax.enterprise.context.spi.Contextual;
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.ProcessAnnotatedType;
 import org.apache.openejb.BeanContext;
 import org.apache.openejb.OpenEJBException;
 import org.apache.webbeans.config.WebBeansContext;
@@ -39,6 +29,17 @@ import org.apache.webbeans.spi.plugins.O
 import org.apache.webbeans.spi.plugins.OpenWebBeansJavaEEPlugin;
 import org.apache.webbeans.util.WebBeansUtil;
 
+import javax.ejb.Stateful;
+import javax.enterprise.context.spi.Context;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Set;
+import java.util.WeakHashMap;
+
 
 public class CdiPlugin extends AbstractOwbPlugin implements OpenWebBeansJavaEEPlugin, OpenWebBeansEjbPlugin {
 
@@ -147,18 +148,7 @@ public class CdiPlugin extends AbstractO
         final CreationalContext<Object> cc = (CreationalContext<Object>) creationalContext;
         final Contextual<Object> component = (Contextual<Object>) bean;
 
-        final boolean openejbBean = component instanceof CdiEjbBean;
-        if (openejbBean) {
-            ((CdiEjbBean) component).setAskedType(interfce);
-        }
-        try {
-            return context.get(component, cc);
-        } finally {
-            if (openejbBean) {
-                ((CdiEjbBean) component).clearAskedType();
-            }
-        }
-
+        return context.get(component, cc);
     }
 
     @Override

Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbHomeProxyHandler.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbHomeProxyHandler.java?rev=1395056&r1=1395055&r2=1395056&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbHomeProxyHandler.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/EjbHomeProxyHandler.java Sat Oct  6 13:41:06 2012
@@ -118,8 +118,11 @@ public abstract class EjbHomeProxyHandle
             Class homeInterface = beanContext.getInterface(interfaceType);
             proxyInterfaces.add(homeInterface);
             proxyInterfaces.add(IntraVmProxy.class);
+            if (BeanType.STATEFUL.equals(beanContext.getComponentType()) || BeanType.MANAGED.equals(beanContext.getComponentType())) {
+                proxyInterfaces.add(BeanContext.Removable.class);
+            }
 
-            return ProxyManager.newProxyInstance(proxyInterfaces.toArray(new Class[]{}), handler);
+            return ProxyManager.newProxyInstance(proxyInterfaces.toArray(new Class[proxyInterfaces.size()]), handler);
         } catch (Exception e) {
             throw new OpenEJBRuntimeException("Can't create EJBHome stub" + e.getMessage(), e);
         }

Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulEjbHomeHandler.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulEjbHomeHandler.java?rev=1395056&r1=1395055&r2=1395056&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulEjbHomeHandler.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulEjbHomeHandler.java Sat Oct  6 13:41:06 2012
@@ -24,6 +24,7 @@ import javax.ejb.RemoveException;
 
 import org.apache.openejb.InterfaceType;
 import org.apache.openejb.BeanContext;
+import org.apache.openejb.cdi.CdiEjbBean;
 import org.apache.openejb.core.ivm.EjbHomeProxyHandler;
 import org.apache.openejb.core.ivm.EjbObjectProxyHandler;
 import org.apache.openejb.util.proxy.ProxyManager;