On a side note, if you are creating "fake beans" by using
BeanManager.createInjectionTarget, at one point it had a side affect of
registering ObserMethodImpls with the NotificantManager.

Joe

On Sat, May 11, 2013 at 5:05 AM, Romain Manni-Bucau
<rmannibu...@gmail.com>wrote:

> To explain a bit for people not having the details:
>
> Basically AT are not thread safe but owb startup objects by app neither. So
> that s ok.
>
> Then if we want it thread safe at runtime we should make AT immutable after
> startup and not do anything lazily.
>
> Finally if it was a fix for tomee please David show me it is the
> case....was the case because we were constructing fake beans at runtime but
> since i ensured it was thread safe now it is no more an issue.
> Le 11 mai 2013 10:23, "Romain Manni-Bucau" <rmannibu...@gmail.com> a
> écrit :
>
> > Should be reverted IMO
> > Le 11 mai 2013 05:21, <dblev...@apache.org> a écrit :
> >
> >> Author: dblevins
> >> Date: Sat May 11 03:20:48 2013
> >> New Revision: 1481253
> >>
> >> URL: http://svn.apache.org/r1481253
> >> Log:
> >> OWB-858: AnnotatedTypeImpl not thread safe
> >> Fixed
> >>
> >> Modified:
> >>
> >>
> openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedTypeImpl.java
> >>
> >>
> openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/portable/AnnotatedTypeImplTest.java
> >>
> >> Modified:
> >>
> openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedTypeImpl.java
> >> URL:
> >>
> http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedTypeImpl.java?rev=1481253&r1=1481252&r2=1481253&view=diff
> >>
> >>
> ==============================================================================
> >> ---
> >>
> openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedTypeImpl.java
> >> (original)
> >> +++
> >>
> openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedTypeImpl.java
> >> Sat May 11 03:20:48 2013
> >> @@ -28,6 +28,10 @@ import java.util.Collections;
> >>  import java.util.HashSet;
> >>  import java.util.List;
> >>  import java.util.Set;
> >> +import java.util.concurrent.Callable;
> >> +import java.util.concurrent.ExecutionException;
> >> +import java.util.concurrent.FutureTask;
> >> +import java.util.concurrent.atomic.AtomicBoolean;
> >>
> >>  import javax.enterprise.inject.spi.AnnotatedConstructor;
> >>  import javax.enterprise.inject.spi.AnnotatedField;
> >> @@ -72,6 +76,19 @@ class AnnotatedTypeImpl<X>
> >>       */
> >>      private Set<AnnotatedMethod<? super X>> methods = null;
> >>
> >> +    private final AtomicBoolean notInitialized = new
> AtomicBoolean(true);
> >> +
> >> +    private final FutureTask initializer = new FutureTask(new
> Callable()
> >> +    {
> >> +        public Object call()
> >> +            throws Exception
> >> +        {
> >> +            init();
> >> +            return null;
> >> +        }
> >> +    });
> >> +
> >> +
> >>      /**
> >>       * Creates a new instance.
> >>       *
> >> @@ -192,11 +209,43 @@ class AnnotatedTypeImpl<X>
> >>       */
> >>      void addAnnotatedConstructor(AnnotatedConstructor<X> constructor)
> >>      {
> >> -        if (constructors == null)
> >> +        ensureInitialized();
> >> +        constructors.add(constructor);
> >> +    }
> >> +
> >> +    private void ensureInitialized()
> >> +    {
> >> +        try
> >>          {
> >> -            init();
> >> +            if (notInitialized.get())
> >> +            {
> >> +                do
> >> +                {
> >> +                    // If this thread is the one to set the state to
> >> "notInitialized=false",
> >> +                    // then this thread is also responsible for calling
> >> the initializer
> >> +                    if (notInitialized.compareAndSet(true, false))
> >> +                    {
> >> +                        initializer.run();
> >> +                    }
> >> +
> >> +                    // Try again.
> >> +                }
> >> +                while (notInitialized.get());
> >> +            }
> >> +
> >> +            // This is the magic blocking call that protects our read
> >> access
> >> +            // The 'get' call will not return until the initializer has
> >> finished running
> >> +            initializer.get();
> >> +        }
> >> +        catch (InterruptedException e)
> >> +        {
> >> +            Thread.interrupted();
> >> +            throw new IllegalStateException("Lazy Initialization of
> >> AnnotatedType failed.", e);
> >> +        }
> >> +        catch (ExecutionException e)
> >> +        {
> >> +            throw new IllegalStateException("Lazy Initialization of
> >> AnnotatedType failed.", e);
> >>          }
> >> -        constructors.add(constructor);
> >>      }
> >>
> >>      /**
> >> @@ -206,10 +255,7 @@ class AnnotatedTypeImpl<X>
> >>       */
> >>      void addAnnotatedField(AnnotatedField<? super X> field)
> >>      {
> >> -        if (constructors == null)
> >> -        {
> >> -            init();
> >> -        }
> >> +        ensureInitialized();
> >>          fields.add(field);
> >>      }
> >>
> >> @@ -220,10 +266,7 @@ class AnnotatedTypeImpl<X>
> >>       */
> >>      void addAnnotatedMethod(AnnotatedMethod<? super X> method)
> >>      {
> >> -        if (constructors == null)
> >> -        {
> >> -            init();
> >> -        }
> >> +        ensureInitialized();
> >>          methods.add(method);
> >>      }
> >>
> >> @@ -233,11 +276,7 @@ class AnnotatedTypeImpl<X>
> >>      @Override
> >>      public Set<AnnotatedConstructor<X>> getConstructors()
> >>      {
> >> -        if (constructors == null)
> >> -        {
> >> -            init();
> >> -        }
> >> -
> >> +        ensureInitialized();
> >>          return Collections.unmodifiableSet(constructors);
> >>      }
> >>
> >> @@ -247,11 +286,7 @@ class AnnotatedTypeImpl<X>
> >>      @Override
> >>      public Set<AnnotatedField<? super X>> getFields()
> >>      {
> >> -        if (constructors == null)
> >> -        {
> >> -            init();
> >> -        }
> >> -
> >> +        ensureInitialized();
> >>          return Collections.unmodifiableSet(fields);
> >>      }
> >>
> >> @@ -261,11 +296,7 @@ class AnnotatedTypeImpl<X>
> >>      @Override
> >>      public Set<AnnotatedMethod<? super X>> getMethods()
> >>      {
> >> -        if (constructors == null)
> >> -        {
> >> -            init();
> >> -        }
> >> -
> >> +        ensureInitialized();
> >>          return Collections.unmodifiableSet(methods);
> >>      }
> >>
> >>
> >> Modified:
> >>
> openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/portable/AnnotatedTypeImplTest.java
> >> URL:
> >>
> http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/portable/AnnotatedTypeImplTest.java?rev=1481253&r1=1481252&r2=1481253&view=diff
> >>
> >>
> ==============================================================================
> >> ---
> >>
> openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/portable/AnnotatedTypeImplTest.java
> >> (original)
> >> +++
> >>
> openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/portable/AnnotatedTypeImplTest.java
> >> Sat May 11 03:20:48 2013
> >> @@ -46,7 +46,6 @@ public class AnnotatedTypeImplTest
> >>      final AtomicInteger exceptions = new AtomicInteger();
> >>
> >>      @Test
> >> -    @Ignore
> >>      public void testGetFields()
> >>          throws Exception
> >>      {
> >> @@ -78,7 +77,6 @@ public class AnnotatedTypeImplTest
> >>      }
> >>
> >>      @Test
> >> -    @Ignore
> >>      public void testGetMethods()
> >>          throws Exception
> >>      {
> >> @@ -110,7 +108,6 @@ public class AnnotatedTypeImplTest
> >>      }
> >>
> >>      @Test
> >> -    @Ignore
> >>      public void testGetConstructors()
> >>          throws Exception
> >>      {
> >>
> >>
> >>
>

Reply via email to