5 Replies Latest reply on Nov 26, 2012 5:25 AM by mkouba

    Injecting a session scope bean in to a HttpSessionListener?

    troup

      The log file of my Java EE 6 web application must make it easy to parse out a given users path through the application. To achieve this I tried to inject a @SessionScoped bean (SessionStore) in to a HttpSessionListener and then set the session id on this bean as follows:

       

      public class ServletSessionListener implements HttpSessionListener {

         

          @Inject

          Instance<SessionStore> sessionStore;

       

           public void sessionCreated(HttpSessionEvent se) {

              System.out.println(se.getSession().getAttributeNames());

              sessionStore.setSessionId(se.getSession().getId());

          }

       

      @Override

          public void sessionDestroyed(HttpSessionEvent se) {

       

          }

      }

       

      I then inject the session scoped bean (SessionStore) into an interceptor that deals with the cross cutting concern of logging:

       

      @Inject

          Instance<SessionStore> sessionStore;

         

          @AroundInvoke

          public Object log(InvocationContext ctx) throws Exception {

              //log method being invoked plus session id here...

       

              Object returnMe = ctx.proceed();

              return returnMe;

          }

       

      Sadly this doesn't work and I get a stack trace when navigating to my app hosted in Glassfish running Weld 1.1.8 final:

       

      java.lang.IllegalArgumentException: Should never reach here at org.apache.catalina.connector.SessionTracker.track(SessionTracker.java:168) at org.apache.catalina.connector.Request.doGetSession(Request.java:2939) at org.apache.catalina.connector.Request.getSession(Request.java:2583)

       

      My current hypothesis is that it is unwise or unsupported to inject something that is session scoped in to a servlet such as HttpSessionListener?

        • 1. Re: Injecting a session scope bean in to a HttpSessionListener?
          mkouba

          Hi Tim,

          I think your code should work (injecting proxy of @SessionScoped bean into a servlet listener), except the invalid usage of javax.enterprise.inject.Instance (you must either use sessionStore.get().setSessionId() or inject SessionStore directly and I would prefer the latter). Actually it works for me on JBoss AS7 and Weld 1.1.5, 1.1.8 and 2.0.0.Aplha4. So it looks like a GF issue. It's hard to guess what "Should never reach here" means

           

          BTW CDI 1.1 will provide HttpSession built-in bean to inject.

          1 of 1 people found this helpful
          • 2. Re: Injecting a session scope bean in to a HttpSessionListener?
            troup

            Hi Martin,

            I had assumed that there would only ever be one instance of the HttpSessionListener created by the container and if so the SessionStore object would be injected only once. If this is correct then the session id of the person who uses that app first would be used for everyone. That is why I thought I should be using Instance<> as this dynamically obtains the instance each time?

             

            I take it I misunderstood the lifecycle of HttpSessionListeners? Or injection? Or both?

             

            Thanks, Tim

            • 3. Re: Injecting a session scope bean in to a HttpSessionListener?
              mkouba

              There is only one instance of the HttpSessionListener I think. However for normal-scoped beans a proxy is injected instead of a direct reference to a bean instance (see also CDI spec, 5.4. "Client proxies"). The client proxy forwards invocations to the actual instance and that's why it's legal to inject e.g. a request scoped bean into a session scoped bean.

              • 4. Re: Injecting a session scope bean in to a HttpSessionListener?
                troup

                Thanks for clarifying that for me.

                 

                I see my SessionStore object being populated as I had hoped when a user accesses my app.

                However, when my interceptor logs the session id it is always null.

                 

                Any ideas why?

                • 5. Re: Injecting a session scope bean in to a HttpSessionListener?
                  mkouba

                  No idea... please post the code snippet and resulting log msg so that we could check it.