You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by st...@apache.org on 2012/07/28 02:13:41 UTC
svn commit: r1366570 - in /openwebbeans/trunk/webbeans-impl/src:
main/java/org/apache/webbeans/decorator/
main/java/org/apache/webbeans/intercept/
main/java/org/apache/webbeans/lifecycle/test/
test/java/org/apache/webbeans/newtests/decorators/tests/
Author: struberg
Date: Sat Jul 28 00:13:40 2012
New Revision: 1366570
URL: http://svn.apache.org/viewvc?rev=1366570&view=rev
Log:
OWB-672 fix Decorator concurrency problems
We only need to create the Decorator stack once, as Decorators
are @Dependent beans to the decorated instance.
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/DelegateHandler.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/WebBeansDecoratorConfig.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorHandler.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/lifecycle/test/OpenWebBeansTestMetaDataDiscoveryService.java
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/decorators/tests/DecoratorAndInterceptorStackTests.java
Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/DelegateHandler.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/DelegateHandler.java?rev=1366570&r1=1366569&r2=1366570&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/DelegateHandler.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/DelegateHandler.java Sat Jul 28 00:13:40 2012
@@ -26,6 +26,7 @@ import java.io.ObjectOutput;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -46,7 +47,14 @@ public class DelegateHandler implements
private static final Logger logger = WebBeansLoggerFacade.getLogger(DelegateHandler.class);
private transient List<Object> decorators;
- private transient int position = 0;
+ private transient ThreadLocal<AtomicInteger> position = new ThreadLocal<AtomicInteger>()
+ {
+ @Override
+ protected AtomicInteger initialValue()
+ {
+ return new AtomicInteger(0);
+ }
+ };
private transient Object actualInstance = null;
@@ -79,10 +87,10 @@ public class DelegateHandler implements
actualInstance = instance;
}
- while (position < decorators.size())
+ while (position.get().intValue() < decorators.size())
{
- Object decorator = decorators.get(position++);
+ Object decorator = decorators.get(position.get().getAndIncrement());
try
{
@@ -97,7 +105,7 @@ public class DelegateHandler implements
}
Object returnValue = decMethod.invoke(decorator, arguments);
- position--;
+ position.remove();
return returnValue;
}
@@ -120,7 +128,7 @@ public class DelegateHandler implements
{
continue;
}
-
+
logger.log(Level.SEVERE, OWBLogConst.ERROR_0012, WebBeansLoggerFacade.args(e.getTargetException(), method.getName(), decorator.getClass().getName()));
if (cause instanceof Exception)
@@ -144,6 +152,8 @@ public class DelegateHandler implements
}
+ position.remove();
+
if (!method.isAccessible())
{
bean.getWebBeansContext().getSecurityService().doPrivilegedSetAccessible(method, true);
Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/WebBeansDecoratorConfig.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/WebBeansDecoratorConfig.java?rev=1366570&r1=1366569&r2=1366570&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/WebBeansDecoratorConfig.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/WebBeansDecoratorConfig.java Sat Jul 28 00:13:40 2012
@@ -145,34 +145,34 @@ public final class WebBeansDecoratorConf
public static List<Object> getDecoratorStack(InjectionTargetBean<?> component, Object instance,
Object delegate, CreationalContextImpl<?> ownerCreationalContext)
{
- List<Object> decoratorStack = new ArrayList<Object>();
- List<Decorator<?>> decoratorList = component.getDecoratorStack();
- Iterator<Decorator<?>> itList = decoratorList.iterator();
- BeanManager manager = component.getWebBeansContext().getBeanManagerImpl();
- while (itList.hasNext())
+ // we need to synchronize on the instance to prevent
+ // creating the decorators too often
+ synchronized(instance)
{
- Object decoratorInstance ;
- WebBeansDecorator<Object> decorator = (WebBeansDecorator<Object>) itList.next();
- decoratorInstance = ownerCreationalContext.getDependentDecorator(instance, decorator);
- if(decoratorInstance == null)
+ List<Object> decoratorStack = new ArrayList<Object>();
+ List<Decorator<?>> decoratorList = component.getDecoratorStack();
+ Iterator<Decorator<?>> itList = decoratorList.iterator();
+ BeanManager manager = component.getWebBeansContext().getBeanManagerImpl();
+ while (itList.hasNext())
{
- decoratorInstance = manager.getReference(decorator, decorator.getBeanClass(), ownerCreationalContext);
-
- decorator.setInjections(decoratorInstance, ownerCreationalContext);
- decorator.setDelegate(decoratorInstance, delegate);
-
- ownerCreationalContext.addDependent(instance, decorator, decoratorInstance);
- }
- else
- {
- //We found an existing decorator instance, update the delegate
- decorator.setDelegate(decoratorInstance, delegate);
+ Object decoratorInstance ;
+ WebBeansDecorator<Object> decorator = (WebBeansDecorator<Object>) itList.next();
+ decoratorInstance = ownerCreationalContext.getDependentDecorator(instance, decorator);
+ if(decoratorInstance == null)
+ {
+ decoratorInstance = manager.getReference(decorator, decorator.getBeanClass(), ownerCreationalContext);
+
+ decorator.setInjections(decoratorInstance, ownerCreationalContext);
+ decorator.setDelegate(decoratorInstance, delegate);
+
+ ownerCreationalContext.addDependent(instance, decorator, decoratorInstance);
+ }
+
+ decoratorStack.add(decoratorInstance);
}
-
- decoratorStack.add(decoratorInstance);
- }
- return decoratorStack;
+ return decoratorStack;
+ }
}
public static Set<Decorator<?>> findDeployedWebBeansDecorator(BeanManagerImpl beanManagerImpl, Set<Type> apiType, Annotation... anns)
Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorHandler.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorHandler.java?rev=1366570&r1=1366569&r2=1366570&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorHandler.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/InterceptorHandler.java Sat Jul 28 00:13:40 2012
@@ -156,6 +156,8 @@ public abstract class InterceptorHandler
protected WebBeansContext webBeansContext;
+ private volatile DelegateHandler delegateHandler = null;
+
/**
* Creates a new handler.
* @param bean proxied bean
@@ -225,30 +227,34 @@ public abstract class InterceptorHandler
!ClassUtil.isObjectMethod(methodName) && bean instanceof InjectionTargetBean<?>)
{
InjectionTargetBean<?> injectionTarget = (InjectionTargetBean<?>) bean;
- DelegateHandler delegateHandler = null;
InterceptorDataImpl decoratorInterceptorDataImpl = null;
//Check method is business method
if (webBeansContext.getInterceptorUtil().isWebBeansBusinessMethod(method))
{
- List<Object> decorators = null;
if (!injectionTarget.getDecoratorStack().isEmpty())
{
- Class<?> proxyClass = webBeansContext.getJavassistProxyFactory().getInterceptorProxyClasses().get(bean);
- if (proxyClass == null)
+ synchronized (this)
{
- ProxyFactory delegateFactory = webBeansContext.getJavassistProxyFactory().createProxyFactory(bean);
- proxyClass = webBeansContext.getJavassistProxyFactory().getProxyClass(delegateFactory);
- webBeansContext.getJavassistProxyFactory().getInterceptorProxyClasses().put(bean, proxyClass);
+ if (delegateHandler == null)
+ {
+ Class<?> proxyClass = webBeansContext.getJavassistProxyFactory().getInterceptorProxyClasses().get(bean);
+ if (proxyClass == null)
+ {
+ ProxyFactory delegateFactory = webBeansContext.getJavassistProxyFactory().createProxyFactory(bean);
+ proxyClass = webBeansContext.getJavassistProxyFactory().getProxyClass(delegateFactory);
+ webBeansContext.getJavassistProxyFactory().getInterceptorProxyClasses().put(bean, proxyClass);
+ }
+ Object delegate = proxyClass.newInstance();
+ delegateHandler = new DelegateHandler(bean);
+ ((ProxyObject)delegate).setHandler(delegateHandler);
+
+ // Gets component decorator stack
+ List<Object> decorators = WebBeansDecoratorConfig.getDecoratorStack(injectionTarget, instance, delegate, ownerCreationalContext);
+ //Sets decorator stack of delegate
+ delegateHandler.setDecorators(decorators);
+ }
}
- Object delegate = proxyClass.newInstance();
- delegateHandler = new DelegateHandler(bean);
- ((ProxyObject)delegate).setHandler(delegateHandler);
-
- // Gets component decorator stack
- decorators = WebBeansDecoratorConfig.getDecoratorStack(injectionTarget, instance, delegate, ownerCreationalContext);
- //Sets decorator stack of delegate
- delegateHandler.setDecorators(decorators);
}
// Run around invoke chain
@@ -261,7 +267,7 @@ public abstract class InterceptorHandler
interceptedMethodMap = new ConcurrentHashMap<Method, List<InterceptorData>>();
}
- if (decorators != null)
+ if (delegateHandler != null)
{
// We have interceptors and decorators, Our delegateHandler will need to be wrapped in an interceptor
WebBeansDecoratorInterceptor lastInterceptor = new WebBeansDecoratorInterceptor(delegateHandler, instance);
@@ -310,7 +316,7 @@ public abstract class InterceptorHandler
// If there are Decorators, allow the delegate handler to
// manage the stack
- if (decorators != null)
+ if (delegateHandler != null)
{
return delegateHandler.invoke(instance, method, proceed, arguments);
}
Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/lifecycle/test/OpenWebBeansTestMetaDataDiscoveryService.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/lifecycle/test/OpenWebBeansTestMetaDataDiscoveryService.java?rev=1366570&r1=1366569&r2=1366570&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/lifecycle/test/OpenWebBeansTestMetaDataDiscoveryService.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/lifecycle/test/OpenWebBeansTestMetaDataDiscoveryService.java Sat Jul 28 00:13:40 2012
@@ -22,11 +22,14 @@ import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javassist.ClassPool;
import org.apache.webbeans.corespi.scanner.AbstractMetaDataDiscovery;
import org.apache.webbeans.exception.WebBeansDeploymentException;
+import org.apache.webbeans.logger.WebBeansLoggerFacade;
import org.apache.webbeans.util.Asserts;
/**
@@ -36,6 +39,8 @@ import org.apache.webbeans.util.Asserts;
*/
public class OpenWebBeansTestMetaDataDiscoveryService extends AbstractMetaDataDiscovery
{
+ private static final Logger logger = WebBeansLoggerFacade.getLogger(OpenWebBeansTestMetaDataDiscoveryService.class);
+
public OpenWebBeansTestMetaDataDiscoveryService()
{
@@ -101,7 +106,7 @@ public class OpenWebBeansTestMetaDataDis
}
catch (IOException e)
{
- e.printStackTrace();
+ logger.log(Level.WARNING, "Problems while scanning class " + clazz.getName());
}
}
Modified: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/decorators/tests/DecoratorAndInterceptorStackTests.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/decorators/tests/DecoratorAndInterceptorStackTests.java?rev=1366570&r1=1366569&r2=1366570&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/decorators/tests/DecoratorAndInterceptorStackTests.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/decorators/tests/DecoratorAndInterceptorStackTests.java Sat Jul 28 00:13:40 2012
@@ -45,7 +45,7 @@ public class DecoratorAndInterceptorStac
{
public static final String PACKAGE_NAME = DecoratorAndInterceptorStackTests.class.getPackage().getName();
- private static final int NUM_THREADS = 50;
+ private static final int NUM_THREADS = 20;
private static final Logger log = Logger.getLogger(DecoratorAndInterceptorStackTests.class.getName());
@@ -82,7 +82,7 @@ public class DecoratorAndInterceptorStac
}
- //X TODO @Test
+ @Test
public void testParallelInterceptorInvocation() throws Exception
{
Collection<Class<?>> classes = new ArrayList<Class<?>>();
@@ -106,6 +106,7 @@ public class DecoratorAndInterceptorStac
for (int i= 0 ; i < NUM_THREADS; i++)
{
threads[i] = new InterceptorTestRunner(outsideBean);
+ threads[i].setName("testthread_" + i);
threads[i].start();
}
@@ -136,7 +137,7 @@ public class DecoratorAndInterceptorStac
// this starts the RequestContext for this very thread
WebBeansContext.currentInstance().getContextFactory().initRequestContext(null);
- for (int i=0; i < 5; i++)
+ for (int i=0; i < 10; i++)
{
outsideBean.doThaStuff();
}