This change in "initRequestContext" fixes the problem:
if (session != null) {
initSessionContext(session);
} else {
sessionContext.set(null);
}
On 30.01.2013, at 21:56, "todor.dimitrov" <[email protected]> wrote:
> I guess this is the bug: in "initRequestContext" the session thread-local is
> not set to null if the session is null and in "destroyRequestContext" the
> session thread-local is also not cleared.
>
>
> private void initRequestContext(ServletRequestEvent event) {
>
> RequestContext rq = new ServletRequestContext();
> rq.setActive(true);
>
> requestContext.set(rq);// set thread local
> if (event != null) {
> HttpServletRequest request = (HttpServletRequest)
> event.getServletRequest();
> ((ServletRequestContext) rq).setServletRequest(request);
>
> if (request != null) {
> //Re-initialize thread local for session
> HttpSession session = request.getSession(false);
>
> if (session != null) {
> initSessionContext(session);
> }
>
> // //Init thread local application context
> // initApplicationContext(event.getServletContext());
> //
> // //Init thread local sigleton context
> // initSingletonContext(event.getServletContext());
> }
> }
> }
>
> private void destroyRequestContext() {
> if (supportsConversation()) { // OWB-595
> cleanupConversation();
> }
>
> //Get context
> RequestContext context = getRequestContext();
>
> //Destroy context
> if (context != null) {
> context.destroy();
> }
>
> // clean up the EL caches after each request
> ELContextStore elStore = ELContextStore.getInstance(false);
> if (elStore != null) {
> elStore.destroyELContextStore();
> }
>
> //Clear thread locals
> requestContext.set(null);
> requestContext.remove();
>
> //Also clear application and singleton context
> // applicationContext.set(null);
> // applicationContext.remove();
>
> //Singleton context
> // singletonContext.set(null);
> // singletonContext.remove();
>
> //Conversation context
> if (null != conversationContext) {
> conversationContext.set(null);
> conversationContext.remove();
> }
>
> RequestScopedBeanInterceptorHandler.removeThreadLocals();
> }
>
>
>
>
> On 30.01.2013, at 21:31, Romain Manni-Bucau <[email protected]> wrote:
>
>> Tomee uses cdiappcontextqsservice. Webbeanqcontextservice cant pass tcks
>>
>> Le 30 janv. 2013 21:25, "todor.dimitrov" <[email protected]> a écrit :
>> The "WebBeansConfigurationListener" class doesn't get loaded and the
>> "WebContextsService#initRequestContext"
>> "WebContextsService#destroyRequestContext" methods are never called. Maybe
>> it's a configuration problem? TomEE+ 1.5.1 uses Tomcat 7, which is a
>> Servlet-3.0 container. Any ideas? Btw, I'm starting the server from Eclipse.
>>
>> Todor
>>
>>
>>
>> On 30.01.2013, at 20:54, Mark Struberg <[email protected]> wrote:
>>
>> > agree, this smells fishy so to say ;)
>> >
>> > On which server does this happen? Native Tomcat + OWB?
>> > The ThreadLocal which holds the current RequestContext is set in
>> > WebBeansConfigurationListener#requestInitialized.
>> >
>> > Please set a breakpoint to see whether this gets invoked properly. This
>> > should finally invoke the WebContextsService#startContext and at the end
>> > of the request the ThreadLocal will be reset to null (and removed) in
>> > WebContextsService#destroyRequestContext
>> >
>> > Maybe you can debug into this and check whether you get the correct
>> > RequestContext?
>> >
>> > LieGrue,
>> > strub
>> >
>> >
>> >
>> >
>> > ----- Original Message -----
>> >> From: Joseph Bergmark <[email protected]>
>> >> To: [email protected]
>> >> Cc:
>> >> Sent: Wednesday, January 30, 2013 7:55 PM
>> >> Subject: Re: CDI, Filter & Session-Scoped Bean
>> >>
>> >> Correct, there should not be thread locals leaking between requests.
>> >>
>> >> On Wed, Jan 30, 2013 at 1:51 PM, todor.dimitrov <[email protected]>
>> >> wrote:
>> >>> Just to be clear, this is not the expected behavior, right? The code
>> >>> should
>> >> be working as is?
>> >>>
>> >>> Thanks for the prompt response,
>> >>>
>> >>> Todor
>> >>>
>> >>>
>> >>> On 30.01.2013, at 19:45, Joseph Bergmark <[email protected]> wrote:
>> >>>
>> >>>> I would be surprised if it was randomly grabbing another session.
>> >>>>
>> >>>> My guess is that either the WebContextService threadlocals are leaking
>> >>>> the contexts themselves, or the threadlocal where we hold onto the the
>> >>>> request in order to lazy initialize the session is leaking, otherwise
>> >>>> I would expect you would receive a ContextNotActive exception if
>> >>>> Session was active on the current request thread.
>> >>>>
>> >>>> Sincerely,
>> >>>>
>> >>>> Joe
>> >>>>
>> >>>> On Wed, Jan 30, 2013 at 12:53 PM, todor.dimitrov
>> >> <[email protected]> wrote:
>> >>>>> Another follow up,
>> >>>>>
>> >>>>> if I add
>> >>>>>
>> >>>>> ((HttpServletRequest)request).getSession(true)
>> >>>>>
>> >>>>> at the beginning of the the doFilter method, then everything works
>> >> as
>> >>>>> expected and the previously described behavior is never observed.
>> >> This means
>> >>>>> that whenever the CDI implementation (OpenWebBeans) cannot retrieve
>> >> the
>> >>>>> session of the current web request, it injects a wrong object (i.e.
>> >> an
>> >>>>> object belonging to another session).
>> >>>>>
>> >>>>>
>> >>>>> On 30.01.2013, at 17:55, "todor.dimitrov"
>> >> <[email protected]> wrote:
>> >>>>>
>> >>>>> Hallo again,
>> >>>>>
>> >>>>> I've just noticed that when this behavior is observed the
>> >> session associated
>> >>>>> with the HTTPServletRequest is null. Somehow Tomcat cannot create a
>> >> session
>> >>>>> object for the request (normally a StandardSession object is
>> >> associated with
>> >>>>> the request). IMHO CDI shouldn't inject an object instance from
>> >> some other
>> >>>>> session if the session of the request is null.
>> >>>>>
>> >>>>>
>> >>>>>
>> >>>>> On 30.01.2013, at 17:39, "todor.dimitrov"
>> >> <[email protected]> wrote:
>> >>>>>
>> >>>>> Hallo,
>> >>>>>
>> >>>>> I have a weird problem when injecting a bean inside a servlet
>> >> filter, which
>> >>>>> is produced by a method of a session-scoped bean:
>> >>>>>
>> >>>>> Filter:
>> >>>>>
>> >>>>> public class AuthenticationFilter implements Filter {
>> >>>>>
>> >>>>> @Inject
>> >>>>> @LoggedIn
>> >>>>> private Instance<User> loggedInUser;
>> >>>>>
>> >>>>> public void doFilter(ServletRequest request, ServletResponse
>> >> response,
>> >>>>> FilterChain chain) throws IOException, ServletException {
>> >>>>>
>> >>>>> final User user = loggedInUser.get();
>> >>>>> if (user != null) {
>> >>>>> // proceed ...
>> >>>>> } else {
>> >>>>> // redirect to login ...
>> >>>>> }
>> >>>>> }
>> >>>>>
>> >>>>> ...
>> >>>>> }
>> >>>>>
>> >>>>> Session-scoped bean with producer method:
>> >>>>>
>> >>>>> @Named
>> >>>>> @SessionScoped
>> >>>>> public class Login implements Serializable {
>> >>>>>
>> >>>>> private User currentUser;
>> >>>>>
>> >>>>> public String login() {
>> >>>>> currentUser = loadUserFromDB(...);
>> >>>>> }
>> >>>>>
>> >>>>> public String logout() {
>> >>>>> currentUser = null;
>> >>>>> }
>> >>>>>
>> >>>>> @Produces
>> >>>>> @LoggedIn
>> >>>>> public User getLoggedInUser() {
>> >>>>> return currentUser;
>> >>>>> }
>> >>>>> }
>> >>>>>
>> >>>>> Qualifier:
>> >>>>>
>> >>>>> @Target({ ElementType.FIELD, ElementType.METHOD })
>> >>>>> @Qualifier
>> >>>>> @Retention(RetentionPolicy.RUNTIME)
>> >>>>> public @interface LoggedIn {
>> >>>>> }
>> >>>>>
>> >>>>> Sometimes the filter incorrectly retrieves the user instance from
>> >> some other
>> >>>>> active session. This happens, however, only the first time the page
>> >> is
>> >>>>> requested by the browser. On subsequent page reloads, the filter
>> >> recognises
>> >>>>> that the user is not logged in. It should be noted that the JSF
>> >>>>> implementation (MyFaces) ALWAYS uses the correct instance of the
>> >>>>> session-scoped bean. I've tried to inject the Login bean
>> >> instead of the User
>> >>>>> object but the result is the same.
>> >>>>>
>> >>>>> Do you have any clues to why I might be experiencing such a
>> >> behavior?
>> >>>>>
>> >>>>>
>> >>>>> Thanks in advance,
>> >>>>>
>> >>>>> Todor
>> >>>>>
>> >>>>>
>> >>>>>
>> >>>
>> >>
>>
>