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
> >>>>>
> >>>>>
> >>>>>
> >>>
> >>
>