Author: struberg
Date: Mon Mar  7 23:20:07 2011
New Revision: 1079019

URL: http://svn.apache.org/viewvc?rev=1079019&view=rev
Log:
OWB-530 fix concurrency problem and cleanup CreationalContext

this also blasts away an ugly public static ThreadLocal.

Modified:
    
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java
    
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/creational/CreationalContextImpl.java
    
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/creational/DependentCreationalContext.java
    
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/AbstractInjectable.java
    
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/InjectableMethods.java
    
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/disposes/beans/DependentBean.java

Modified: 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java?rev=1079019&r1=1079018&r2=1079019&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java
 Mon Mar  7 23:20:07 2011
@@ -236,22 +236,13 @@ public abstract class AbstractOwbBean<T>
                 destroyInstance(instance,creationalContext);
             }
             
-            //Setting destroying instance
-            CreationalContextImpl.currentRemoveObject.set(instance);
-            
             //Destory dependent instances
-            creationalContext.release();                
-                                                
+            creationalContext.release();
         }
         catch(Exception e)
         {
             getLogger().fatal(e, OWBLogConst.FATAL_0001, this);
         }
-        finally
-        {
-            CreationalContextImpl.currentRemoveObject.set(null);
-            CreationalContextImpl.currentRemoveObject.remove();
-        }
     }
 
     /**

Modified: 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/creational/CreationalContextImpl.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/creational/CreationalContextImpl.java?rev=1079019&r1=1079018&r2=1079019&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/creational/CreationalContextImpl.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/creational/CreationalContextImpl.java
 Mon Mar  7 23:20:07 2011
@@ -30,6 +30,7 @@ import javax.enterprise.inject.spi.Inter
 
 import org.apache.webbeans.config.WebBeansContext;
 import 
org.apache.webbeans.context.creational.DependentCreationalContext.DependentType;
+import org.apache.webbeans.exception.WebBeansException;
 import org.apache.webbeans.util.Asserts;
 import org.apache.webbeans.util.WebBeansUtil;
 
@@ -48,17 +49,19 @@ public class CreationalContextImpl<T> im
     private Map<Object, List<DependentCreationalContext<?>>> dependentObjects 
= null;
 
     /**Contextual bean*/
-    private volatile Contextual<T> contextual = null;
+    private Contextual<T> contextual = null;
         
     /**Ejb interceptors*/
     //contextual instance --> interceptors
     private ConcurrentMap<Object, List<EjbInterceptorContext>> ejbInterceptors 
= null;
 
-    /**When bean object is destroyed it is set*/
-    //X TODO refactor. public static variables are utterly ugly
-    public static ThreadLocal<Object> currentRemoveObject = new 
ThreadLocal<Object>();
-
     private WebBeansContext webBeansContext;
+    
+    /**
+     * This flag will get set to <code>true</code> to prevent recursive loops 
while destroying
+     * the CreationContext.
+     */
+    private boolean destroying = false;
 
     /**
      * Package private
@@ -146,13 +149,14 @@ public class CreationalContextImpl<T> im
     /**
      * Adds given dependent instance to the map.
      * 
+     * @param ownerInstance the contextual instance our dependent instance got 
injected into
      * @param dependent dependent contextual
      * @param instance dependent instance
      */
     public <K> void addDependent(Object ownerInstance, Contextual<K> 
dependent, Object instance)
     {
         Asserts.assertNotNull(dependent,"dependent parameter cannot be null");
-        
+
         if(instance != null)
         {
             DependentCreationalContext<K> dependentCreational = new 
DependentCreationalContext<K>(dependent);
@@ -259,59 +263,17 @@ public class CreationalContextImpl<T> im
             }
         }
         return null;
-    }    
-    
-    /**
-     * Removes dependent objects.
-     */
-    @SuppressWarnings("unchecked")
-    public void  removeDependents(Object ownerInstance)
-    {
-        if(ownerInstance == null || dependentObjects == null)
-        {
-            return;
-        }
-
-
-        synchronized(this)
-        {
-            List<DependentCreationalContext<?>> values = 
this.dependentObjects.get(ownerInstance);
-            if(values != null)
-            {
-                final CreationalContextFactory contextFactory = 
webBeansContext.getCreationalContextFactory();
-                Iterator<?> iterator = values.iterator();
-                while(iterator.hasNext())
-                {
-                    DependentCreationalContext<T> dependent = 
(DependentCreationalContext<T>)iterator.next();
-                    
dependent.getContextual().destroy((T)dependent.getInstance(), 
contextFactory.getCreationalContext(dependent.getContextual()));
-                }
-
-                this.dependentObjects.remove(ownerInstance);
-            }
-        }
-
-        if (this.ejbInterceptors != null)
-        {
-            List<EjbInterceptorContext> interceptors = 
this.ejbInterceptors.get(ownerInstance);
-            if(interceptors != null)
-            {
-                for(EjbInterceptorContext intereptor : interceptors)
-                {
-                    intereptor.getInjectorInstance().destroy();
-                }
-            }
-
-            this.ejbInterceptors.remove(ownerInstance);
-        }
     }
-    
+
     @SuppressWarnings("unchecked")
     public void removeAllDependents()
     {
-        if (dependentObjects == null)
+        if (dependentObjects == null || destroying)
         {
             return;
         }
+        
+        destroying = true;
 
         synchronized(this)
         {
@@ -320,12 +282,22 @@ public class CreationalContextImpl<T> im
             {
                 for(List<DependentCreationalContext<?>> value : values)
                 {
-                    Iterator<?> iterator = value.iterator();
-                    while(iterator.hasNext())
+                    // this is kind of an emergency valve...
+                    int maxRemoval = value.size() * 3;
+                    while(!value.isEmpty() && maxRemoval > 0)
+                    {
+                        // we don't use an iterator because the destroyal 
might register a 
+                        // fresh PreDestroy interceptor as dependent object...
+                        DependentCreationalContext<T> dependent = 
(DependentCreationalContext<T>)value.get(0);
+                        
dependent.getContextual().destroy((T)dependent.getInstance(), this);
+                        
+                        value.remove(0);
+                        maxRemoval--;
+                    }
+                    
+                    if (maxRemoval == 0)
                     {
-                        DependentCreationalContext<T> dependent = 
(DependentCreationalContext<T>)iterator.next();
-                        CreationalContextFactory contextFactory = 
webBeansContext.getCreationalContextFactory();
-                        
dependent.getContextual().destroy((T)dependent.getInstance(), 
contextFactory.getCreationalContext(dependent.getContextual()));
+                        throw new WebBeansException("infinite loop detected 
while destroying bean " + contextual);
                     }
                 }
             }
@@ -362,14 +334,7 @@ public class CreationalContextImpl<T> im
     @Override
     public void release()
     {
-        if(currentRemoveObject.get() == null)
-        {
-            removeAllDependents();
-        }
-        else
-        {
-            removeDependents(currentRemoveObject.get());   
-        }
+        removeAllDependents();
     }
     
     /**

Modified: 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/creational/DependentCreationalContext.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/creational/DependentCreationalContext.java?rev=1079019&r1=1079018&r2=1079019&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/creational/DependentCreationalContext.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/creational/DependentCreationalContext.java
 Mon Mar  7 23:20:07 2011
@@ -29,6 +29,10 @@ import javax.enterprise.context.spi.Cont
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.util.WebBeansUtil;
 
+/**
+ * This class contains creation information about &#0064;Dependent scoped 
+ * contextual instances.
+ */
 public class DependentCreationalContext<S> implements Serializable
 {
     private static final long serialVersionUID = 1L;

Modified: 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/AbstractInjectable.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/AbstractInjectable.java?rev=1079019&r1=1079018&r2=1079019&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/AbstractInjectable.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/AbstractInjectable.java
 Mon Mar  7 23:20:07 2011
@@ -145,9 +145,9 @@ public abstract class AbstractInjectable
             if(instanceUnderInjection.get() != null)
             {
                 
((CreationalContextImpl<?>)this.injectionOwnerCreationalContext).addDependent(instanceUnderInjection.get(),injectedBean,
 injected);   
-            }   
+            }
         }
-            
+
         return injected;
     }
     

Modified: 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/InjectableMethods.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/InjectableMethods.java?rev=1079019&r1=1079018&r2=1079019&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/InjectableMethods.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/InjectableMethods.java
 Mon Mar  7 23:20:07 2011
@@ -36,7 +36,6 @@ import org.apache.webbeans.annotation.De
 import org.apache.webbeans.component.OwbBean;
 import org.apache.webbeans.component.ProducerMethodBean;
 import org.apache.webbeans.container.InjectionResolver;
-import org.apache.webbeans.context.creational.CreationalContextImpl;
 import org.apache.webbeans.exception.WebBeansException;
 import org.apache.webbeans.util.SecurityUtil;
 
@@ -147,15 +146,6 @@ public class InjectableMethods<T> extend
         }
     }
     
-    /**
-     * Destroy dependent objects of the bean.
-     */
-    public void destroyDependentInjectionPoints(Object ownerInstance)
-    {
-        CreationalContextImpl<?> ownerCreational = (CreationalContextImpl<?>) 
this.injectionOwnerCreationalContext;
-        ownerCreational.removeDependents(ownerInstance);
-    }
-    
     public Map<Bean<?>,Object> getDependentBeanParameters()
     {
         return this.dependentParameters;

Modified: 
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/disposes/beans/DependentBean.java
URL: 
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/disposes/beans/DependentBean.java?rev=1079019&r1=1079018&r2=1079019&view=diff
==============================================================================
--- 
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/disposes/beans/DependentBean.java
 (original)
+++ 
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/disposes/beans/DependentBean.java
 Mon Mar  7 23:20:07 2011
@@ -45,7 +45,7 @@ public class DependentBean
         model.setValue(true);
         model.setId(index++);
         if (producedModel == null) {
-               producedModel = model;
+            producedModel = model;
         }
        System.out.println("produced DependentModel=" + model);
         return model;


Reply via email to