Markus Jung created OWB-1469:
--------------------------------

             Summary: OwbRequestContextController is not threadsafe
                 Key: OWB-1469
                 URL: https://issues.apache.org/jira/browse/OWB-1469
             Project: OpenWebBeans
          Issue Type: Bug
          Components: Core
    Affects Versions: 4.1.0
            Reporter: Markus Jung


{{org.apache.webbeans.context.control.OwbRequestContextController}} keeps its 
activation state in a plain instance field:
{code:java}
private boolean enabled;

@Override
public boolean activate()
{
    final Context ctx = contextsService.getCurrentContext(RequestScoped.class, 
false);
    enabled = ctx == null || !ctx.isActive();
    if (enabled)
    {
        contextsService.startContext(RequestScoped.class, null);
    }
    return enabled;
}

@Override
public void deactivate() throws ContextNotActiveException
{
    if (enabled)
    {
        contextsService.endContext(RequestScoped.class, null);
        RequestScopedBeanInterceptorHandler.removeThreadLocals();
        enabled = false;
    }
}
{code}
The contexts managed by {{ContextsService}} are thread-local, but the 
{{enabled}} flag is per controller instance. When one controller instance is 
used from more than one thread (e.g. a {{RequestContextController}} injected 
into an {{@ApplicationScoped}} bean that submits tasks to an 
{{{}ExecutorService{}}}), the following interleaving occurs:
 # Thread A: {{activate()}} -> {{{}enabled = true{}}}, context started on A.
 # Thread B: {{activate()}} -> writes {{{}enabled = true{}}}.
 # Thread A: {{deactivate()}} -> ends A's context, {{{}enabled = false{}}}.
 # Thread B: reaches {{if (enabled)}} — the check *re-reads the field* instead 
of using the value it just computed — reads {{{}false{}}}, so {{startContext}} 
is {*}skipped{*}. {{activate()}} returns {{false}} although no request context 
is active on thread B.

Thread B then runs with no request context and the first touch of any 
{{@RequestScoped}} normal-scope proxy fails with:
{noformat}
jakarta.enterprise.context.ContextNotActiveException: WebBeans context with 
scope type annotation @RequestScoped does not exist within current thread
    at 
org.apache.webbeans.container.BeanManagerImpl.getContext(BeanManagerImpl.java:345)
    at 
org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:89)
    at 
org.apache.webbeans.intercept.RequestScopedBeanInterceptorHandler.getContextualInstance(RequestScopedBeanInterceptorHandler.java:76)
    at 
org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.get(NormalScopedBeanInterceptorHandler.java:71)
{noformat}

Same probleme exists the other way around (and is more likely to hit silently), 
a thread that activated RequestContext may not reliably end it because 
{{enabled}} may have been modified by another thread calling deactivate in the 
meantime



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to