[ 
https://issues.apache.org/jira/browse/OWB-1469?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18097813#comment-18097813
 ] 

Markus Jung commented on OWB-1469:
----------------------------------

Reading through the spec this can be very well considered to be a user error 
([https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1#activating_request_context]):
{noformat}
The object should be considered stateful, invoking the same instance on 
different threads may not work properly, non-portable behavior may 
occur.{noformat}



> 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
>            Priority: Major
>
> {{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