Re: [weld-dev] RquestScoped not active inside WeldInitialListener.requestDestroyed

2018-06-14 Thread Benjamin Confino
Thanks Martin, this is useful context

Regards
Benjamin



From:   Martin Kouba 
To: Benjamin Confino , Matej Novotny 

Cc: weld-dev@lists.jboss.org
Date:   14/06/2018 10:28
Subject:Re: [weld-dev] RquestScoped not active inside 
WeldInitialListener.requestDestroyed



Hello Benjamin,

First of all, there is no guarantee that the request context is active 
during @PreDestroy of a @SessionScoped bean (unlike @PostConstruct 
callback of any bean). And it is certainly not active when an http 
session times out. And that's the reason why 
UserSessionData.preDestroy(), which invokes @RequestScoped MyPrincipal 
created by PrincipalProducer.produce(), is not correct.

In this particular case, Weld follows the spec and destroys the session 
context "at the very end of the request in which invalidate() was 
called" [1]. So it's not destroyed immediately when invalidate() is 
called. Furthermore, the order in which HTTP contexts are destroyed is 
not defined. If needed, Weld first destroys conversation, then request 
and finally session context. That's why the customer gets 
ContextNotActiveException.

It's more like a chicken-egg problem. And since the session context has 
"wider" scope I think it makes more sense to allow @RequestScoped beans 
to access the session context in @PreDestroy callbacks and not vice versa.

Martin

[1]
http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#session_context_ee


Dne 13.6.2018 v 16:23 Benjamin Confino napsal(a):
> Hello Matej
> 
> I spoke to the customer, who kindly provided the following source on 
> github: 
https://github.com/elexx/was9_bugs/tree/master/bug21

> 
> It looks like the code is bound to a @PreDestroy method on the 
> @SessionScoped annotated class UserSessionData. The PreDestroy fires 
> because session.invalidate() is called in LogoutServlet.
> 
> Looking at 
> 
http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#request_contextit 

> doesn't seem like any of the four cases when the spec applies here. We 
> have left LogoutServlet's service() method before the new thread calls 
> the preDestroy method. So I think this is an application issue.
> 
> Regards
> Benjamin
> 
> 
> 
> From: Matej Novotny 
> To: Benjamin Confino 
> Cc: weld-dev@lists.jboss.org
> Date: 12/06/2018 13:17
> Subject: Re: [weld-dev] RquestScoped not active inside 
>   WeldInitialListener.requestDestroyed
> 
> 
> 
> 
> Hi,
> 
> what does user code look like?
> Does he have an event listener?
> 
> I'd say this depends on *precisely* what is his code bound to.
> At some point (after the invalidation), you should be getting 
> ContextNotActiveException so I guess we need to know more about the code 

> to determine this.
> If the user has some code bound to "generic" servlet events, it may well 

> happen that they fire after CDI events.
> 
> Matej
> 
> - Original Message -
>  > From: "Benjamin Confino" 
>  > To: weld-dev@lists.jboss.org
>  > Sent: Monday, June 11, 2018 10:46:31 AM
>  > Subject: [weld-dev] RquestScoped not active inside 
> WeldInitialListener.requestDestroyed
>  >
>  > Hello.
>  >
>  > I have a customer who's getting ContextNotActiveExceptions for the
>  > RequestScoped Context. This happens inside the invocation of
>  > WeldInitialListener.requestDestroyed() after the customer's 
application
>  > invalidated the session. 
DefaultLifecycleCallbackInvoker.invokeMethods
>  > invokes a method in application code, which calls a method on a 
> proxy, which
>  > results in weld attempting to get the context from the BeanManager 
> and the
>  > ContextNotActiveException.
>  >
>  > My question is simple. Is this an integration issue or is this an 
> application
>  > issue?
>  >
>  > Here is the stack:
>  >
>  > org.jboss.weld.context.ContextNotActiveException: WELD-001303: No 
active
>  > contexts for scope type javax.enterprise.context.RequestScoped
>  > at
>  > 
> 
org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:731)
>  > at
>  > 
> 
org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:89)
>  > at
>  > 
> 
org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:164)
>  > at
>  > 
> 
org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
>  > at
>  > 
> 
org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
>  > at
>  > 
> 
org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)
>  > $$_WeldClientProxy.getUserId(Unknown Source)
>  >
>  > 
>  >
>  > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>  > at
>  > 
> 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
>  > at
>  > 
> 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
>  > at 

Re: [weld-dev] RquestScoped not active inside WeldInitialListener.requestDestroyed

2018-06-14 Thread Martin Kouba
Hello Benjamin,

First of all, there is no guarantee that the request context is active 
during @PreDestroy of a @SessionScoped bean (unlike @PostConstruct 
callback of any bean). And it is certainly not active when an http 
session times out. And that's the reason why 
UserSessionData.preDestroy(), which invokes @RequestScoped MyPrincipal 
created by PrincipalProducer.produce(), is not correct.

In this particular case, Weld follows the spec and destroys the session 
context "at the very end of the request in which invalidate() was 
called" [1]. So it's not destroyed immediately when invalidate() is 
called. Furthermore, the order in which HTTP contexts are destroyed is 
not defined. If needed, Weld first destroys conversation, then request 
and finally session context. That's why the customer gets 
ContextNotActiveException.

It's more like a chicken-egg problem. And since the session context has 
"wider" scope I think it makes more sense to allow @RequestScoped beans 
to access the session context in @PreDestroy callbacks and not vice versa.

Martin

[1]
http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#session_context_ee

Dne 13.6.2018 v 16:23 Benjamin Confino napsal(a):
> Hello Matej
> 
> I spoke to the customer, who kindly provided the following source on 
> github: https://github.com/elexx/was9_bugs/tree/master/bug21
> 
> It looks like the code is bound to a @PreDestroy method on the 
> @SessionScoped annotated class UserSessionData. The PreDestroy fires 
> because session.invalidate() is called in LogoutServlet.
> 
> Looking at 
> http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#request_contextit 
> doesn't seem like any of the four cases when the spec applies here. We 
> have left LogoutServlet's service() method before the new thread calls 
> the preDestroy method. So I think this is an application issue.
> 
> Regards
> Benjamin
> 
> 
> 
> From: Matej Novotny 
> To: Benjamin Confino 
> Cc: weld-dev@lists.jboss.org
> Date: 12/06/2018 13:17
> Subject: Re: [weld-dev] RquestScoped not active inside   
>   WeldInitialListener.requestDestroyed
> 
> 
> 
> 
> Hi,
> 
> what does user code look like?
> Does he have an event listener?
> 
> I'd say this depends on *precisely* what is his code bound to.
> At some point (after the invalidation), you should be getting 
> ContextNotActiveException so I guess we need to know more about the code 
> to determine this.
> If the user has some code bound to "generic" servlet events, it may well 
> happen that they fire after CDI events.
> 
> Matej
> 
> - Original Message -
>  > From: "Benjamin Confino" 
>  > To: weld-dev@lists.jboss.org
>  > Sent: Monday, June 11, 2018 10:46:31 AM
>  > Subject: [weld-dev] RquestScoped not active inside   
> WeldInitialListener.requestDestroyed
>  >
>  > Hello.
>  >
>  > I have a customer who's getting ContextNotActiveExceptions for the
>  > RequestScoped Context. This happens inside the invocation of
>  > WeldInitialListener.requestDestroyed() after the customer's application
>  > invalidated the session. DefaultLifecycleCallbackInvoker.invokeMethods
>  > invokes a method in application code, which calls a method on a 
> proxy, which
>  > results in weld attempting to get the context from the BeanManager 
> and the
>  > ContextNotActiveException.
>  >
>  > My question is simple. Is this an integration issue or is this an 
> application
>  > issue?
>  >
>  > Here is the stack:
>  >
>  > org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active
>  > contexts for scope type javax.enterprise.context.RequestScoped
>  > at
>  > 
> org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:731)
>  > at
>  > 
> org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:89)
>  > at
>  > 
> org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:164)
>  > at
>  > 
> org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
>  > at
>  > 
> org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
>  > at
>  > 
> org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)
>  > $$_WeldClientProxy.getUserId(Unknown Source)
>  >
>  > 
>  >
>  > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>  > at
>  > 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
>  > at
>  > 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
>  > at java.lang.reflect.Method.invoke(Method.java:508)
>  > at
>  > 
> org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.invokeMethods(DefaultLifecycleCallbackInvoker.java:97)
>  > at
>  > 
> org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.preDestroy(DefaultLifecycleCallbackInvoker.java:90)
>  >