[
https://issues.apache.org/jira/browse/OWB-1469?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Markus Jung resolved OWB-1469.
------------------------------
Resolution: Not A Problem
> 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)