9 Replies Latest reply: Jan 28, 2013 12:13 AM by Rahul Razdan RSS

    seam 3 IllegalStateException after session timeout

    Bob Shanahan Newbie

      I'm running a simple Seam 3 app on JBoss 7.1.1.Final with the following in WEB-INF/lib:

       

      prettyfaces-jsf2-3.3.3.jar

      richfaces-components-api-4.2.0.Final.jar

      richfaces-components-ui-4.2.0.Final.jar

      richfaces-core-api-4.2.0.Final.jar

      richfaces-core-impl-4.2.0.Final.jar

      seam-faces-3.1.0.Final.jar

      seam-faces-api-3.1.0.Final.jar

      seam-international-3.1.0.Final.jar

      seam-international-api-3.1.0.Final.jar

      seam-persistence-3.1.0.Final.jar

      seam-persistence-api-3.1.0.Final.jar

      seam-security-3.1.0.Final.jar

      seam-security-api-3.1.0.Final.jar

      seam-spring-core-3.1.0.Final.jar

      seam-transaction-3.1.0.Final.jar

      seam-transaction-api-3.1.0.Final.jar

      solder-api-3.1.0.Final.jar

      solder-impl-3.1.0.Final.jar

      solder-logging-3.1.0.Final.jar

       

      plus the usual logging, etc. jars.

       

      I have a trivial authenticator that allows any username/password pair to authenticate:

       

      public class PortalAuthenticator extends BaseAuthenticator implements Authenticator 
      {
          private static final Logger log = Logger.getLogger(Authenticator.class);
      
          @Inject
          Identity identity;
          @Inject
          Credentials credentials;
      
          @Override
          public void authenticate()
          {
                    setStatus(AuthenticationStatus.SUCCESS);
                    setUser(new SimpleUser(credentials.getUsername()));
                    identity.addRole("ROLE_USER", "USERS", "GROUP");
           }
       }
      

       

       

      and a simple login.xhtml page:

       

       

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:a4j="http://richfaces.org/a4j"
          xmlns:rich="http://richfaces.org/rich">
      
      
        <h:head>
          <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
          <title>test - login</title>
          <link href="css/theme.css" rel="stylesheet" type="text/css"/>
          <link href="css/layout.css" rel="stylesheet" type="text/css"/>
          
        </h:head>
        
        <body onload="setFocus('login:username'); checkJavaScript();">
                  <div id="container">
                            <div style="position: relative; overflow-y: hidden; padding: 10px; margin-top: 12%; margin-left: auto; margin-right: auto; width: 500px; background: #fff; border: 0px solid">
                                      <div style="position: relative; margin-left: auto; margin-right: auto; width: 320px; border: 0px solid">
                                              <span style="font: bold 34pt arial narrow, sans-serif; color: black; position: relative; margin-top: 0%"><img src="images/authen2cate_logo_sprite.png" /></span>
                                    </div>
                                      <div style="font-family: sans-serif; font-size: small; width: 300px; margin-left: auto; position: relative; margin-top: auto; margin-bottom: 2%; margin-right: auto; padding: 10px; background-color: #afafaf;">
                                               <h:form id="login">
                                                        <rich:panel style="background: #afafaf; border: 0px;">
                                                      <h:panelGrid columns="2" rowClasses="prop" columnClasses="name,value">
                                                          <h:outputLabel for="username">User Name: </h:outputLabel>
                                                    <h:inputText id="username" 
                                                                  value="#{credentials.username}" style="width: 15em"/>
                                                    <h:outputLabel for="password">Password: </h:outputLabel>
                                                    <h:inputSecret id="password" 
                                                                    value="#{credentials.password}" style="width: 15em"/>
                                                </h:panelGrid>
                                                <div style="height: 12px"/>
                                                      <div class="actionButtons" style="display: none">
                                                          <h:commandButton value="Login" action="#{identity.login}" style="width: 50px"/>
                                                      </div>
                                            </rich:panel>
                                        </h:form>
                              </div>
                              <div style="font-family: sans-serif; font-size: small; color: red; width: 300px; margin-left: auto; position: relative; margin-top: auto; margin-bottom: 2%; margin-right: auto; padding: 5px; background-color: #ffff; border: 0px solid">
                                        <h:messages />
                              </div>
                                    <div id="footer" >&amp;#169; <script>document.write((new Date()).getFullYear());</script> xxx. All rights reserved. Build: #{appVersion.build}</div>
                                    <div style="clear: both"/>
                          </div>
                  </div>
      
      
        </body>
      </html>
      

       

       

      @ViewConfig as follows:

       

       

      @ViewConfig
      public interface PagesConfig {
      
       static enum Pages
                {
        @FacesRedirect
        @ViewPattern("/view/*")
              @LoginView("/login.xhtml")
              @LoggedIn
              ALL,
              
              @FacesRedirect
              @ViewPattern("/login.xhtml")
              LOGIN
              
                }
      }
      
      

       

       

      faces-config.xml

       

       

          <navigation-rule>
              <navigation-case>
                  <from-action>#{identity.login}</from-action>
                  <if>#{identity.loggedIn}</if>
                  <to-view-id>/view/home.xhtml</to-view-id>
                  <redirect/>
              </navigation-case>
      
              <navigation-case>
                  <from-action>#{identity.login}</from-action>
                  <from-outcome>failed</from-outcome>
                  <to-view-id>/login.xhtml</to-view-id>
              </navigation-case>
      
          </navigation-rule>
      
      

       

       

      The exception occurs when the session times out and the user navigates anywhere within /view/*. The redirect to /login.xhtml works, but then upon login I get this:

       

       

      13:06:07,656 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/portal].[Faces Servlet]] (http--0.0.0.0-8080-1) Servlet.service() for servlet Faces Servlet threw exception: javax.enterprise.event.ObserverException
                at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [rt.jar:1.6.0_31]
                at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) [rt.jar:1.6.0_31]
                at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) [rt.jar:1.6.0_31]
                at java.lang.reflect.Constructor.newInstance(Constructor.java:513) [rt.jar:1.6.0_31]
                at java.lang.Class.newInstance0(Class.java:355) [rt.jar:1.6.0_31]
                at java.lang.Class.newInstance(Class.java:308) [rt.jar:1.6.0_31]
                at org.jboss.weld.util.reflection.SecureReflections$16.work(SecureReflections.java:343) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInstantiation(SecureReflectionAccess.java:173) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.weld.util.reflection.SecureReflections.newInstance(SecureReflections.java:340) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.weld.injection.Exceptions.rethrowException(Exceptions.java:33) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.weld.injection.Exceptions.rethrowException(Exceptions.java:73) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.weld.injection.MethodInjectionPoint.invokeOnInstanceWithSpecialValue(MethodInjectionPoint.java:162) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:241) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:229) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:207) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.weld.manager.BeanManagerImpl.notifyObservers(BeanManagerImpl.java:569) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:559) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:554) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.jboss.solder.servlet.exception.CatchExceptionFilter.doFilter(CatchExceptionFilter.java:74) [solder-impl-3.1.0.Final.jar:3.1.0.Final]
                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
                at org.jboss.solder.servlet.event.ServletEventBridgeFilter.doFilter(ServletEventBridgeFilter.java:74) [solder-impl-3.1.0.Final.jar:3.1.0.Final]
                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
                at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:145) [prettyfaces-jsf2-3.3.3.jar:]
                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
                at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
                at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
                at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
                at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
                at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
                at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
                at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
                at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
                at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
                at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
                at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_31]
      Caused by: javax.servlet.ServletException
                at javax.faces.webapp.FacesServlet.service(FacesServlet.java:606) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
                at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
                at org.jboss.solder.servlet.exception.CatchExceptionFilter.doFilter(CatchExceptionFilter.java:65) [solder-impl-3.1.0.Final.jar:3.1.0.Final]
                ... 19 more
      Caused by: java.lang.IllegalStateException
                at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:436) [jbossweb-7.0.13.Final.jar:]
                at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:170) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
                at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:170) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
                at org.jboss.weld.servlet.ConversationPropagationFilter$1.sendRedirect(ConversationPropagationFilter.java:83) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
                at com.sun.faces.context.ExternalContextImpl.redirect(ExternalContextImpl.java:576) [jsf-impl-2.1.7-jbossorg-2.jar:]
                at javax.faces.context.ExternalContextWrapper.redirect(ExternalContextWrapper.java:462) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
                at javax.faces.context.ExternalContextWrapper.redirect(ExternalContextWrapper.java:462) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
                at org.jboss.seam.faces.environment.SeamExternalContext.redirect(SeamExternalContext.java:71) [seam-faces-3.1.0.Final.jar:3.1.0.Final]
                at org.jboss.seam.faces.environment.SeamExternalContext$Proxy$_$$_WeldClientProxy.redirect(SeamExternalContext$Proxy$_$$_WeldClientProxy.java) [seam-faces-3.1.0.Final.jar:3.1.0.Final]
                at com.sun.faces.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:182) [jsf-impl-2.1.7-jbossorg-2.jar:]
                at com.ocpsoft.pretty.faces.application.PrettyNavigationHandler.handleNavigation(PrettyNavigationHandler.java:64) [prettyfaces-jsf2-3.3.3.jar:]
                at org.jboss.seam.faces.event.SeamPreNavigationHandler.handleNavigation(SeamPreNavigationHandler.java:63) [seam-faces-3.1.0.Final.jar:3.1.0.Final]
                at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:130) [jsf-impl-2.1.7-jbossorg-2.jar:]
                at javax.faces.component.UICommand.broadcast(UICommand.java:315) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
                at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
                at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
                at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) [jsf-impl-2.1.7-jbossorg-2.jar:]
                at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.7-jbossorg-2.jar:]
                at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl-2.1.7-jbossorg-2.jar:]
                at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
                ... 25 more
      
      

       

       

      Would greatly appreciate any insights to resolving or workarounds.

        • 1. Re: seam 3 IllegalStateException after session timeout
          Bob Shanahan Newbie

          I understand that there is a conflict between the @ViewConfig and faces-config post auth navigation rule (when the user arrives at login from another page within the app), but how can I reconcile? I've not been able to determine a @ViewConfig configuration that will handle initial post auth redirect to my app home page. I'd perfer to handle it all in @ViewConfig rather than split config across files.

          • 2. Re: seam 3 IllegalStateException after session timeout
            Bernard Labno Master

            Bob, your post login navigation rule in faces-config.xml conflicts with seam's LoginListener. You must remove that rule.

            • 3. Re: seam 3 IllegalStateException after session timeout
              Bob Shanahan Newbie

              Thanks Bernard. To achieve redirect after login w/out captured view I added the following after successfull authentication.

               

               

              (sorry, no code formatting available)

               

               

                      String PRE_LOGIN_URL = LoginListener.class.getName() + "_PRE_LOGIN_URL";

                      String redirectURL = (String) facesContext.getExternalContext().getSessionMap().get(PRE_LOGIN_URL);

               

                      if (redirectURL == null) {

                          log.debug("Replacing Redirect URL");

                          redirectURL = httpServletRequest.getRequestURL().toString();

                          redirectURL = redirectURL.replace("/login.html", "/view/home.html");

                      }

               

                      facesContext.getExternalContext().getSessionMap().put(PRE_LOGIN_URL, redirectURL);

              • 4. Re: seam 3 IllegalStateException after session timeout
                Rahul Razdan Newbie

                hi Bob,

                 

                i was also facing the same issue , i have login.xhtml related navigations in faces-config.xml .

                 

                so can you please bring more light on the above solution that you mentioned.

                 

                 

                Thanks a lot !!

                • 5. Re: seam 3 IllegalStateException after session timeout
                  Bob Shanahan Newbie

                  Hi Rahul. The redirect workaround is part of my authenticator.

                   

                   

                   

                  @Named("portalAuthenticator")
                  public class PortalAuthenticator extends BaseAuthenticator implements Authenticator 
                  {
                      private static final Logger log = Logger.getLogger(Authenticator.class);
                  
                  
                      @Inject
                      Identity identity;
                      @Inject
                      Credentials credentials;
                      @Inject
                      AuthenticationManager authenticationManager;
                  
                  
                      @Override
                      public void authenticate()
                      {
                                Authentication a = new UsernamePasswordAuthenticationToken(credentials.getUsername(), 
                                                    ((PasswordCredential)credentials.getCredential()).getValue());
                                
                                try
                                {
                                    Authentication principal = authenticationManager.authenticate(a);
                                    
                                    setStatus(AuthenticationStatus.SUCCESS);
                                    setUser(new SimpleUser(principal.getName()));
                  
                  
                                    for(GrantedAuthority g: principal.getAuthorities())
                                    {
                                        identity.addRole(g.getAuthority(), "USERS", "GROUP");
                                    }
                                    
                                    log.info("User " + principal.getName() + " logged in.");
                                    
                                    //A bug in seam faces causes faces-config nav to homepage
                                    //to fail after a session timeout.
                                    overrideRedirectFromLogin();
                                }
                                catch(AuthenticationException e)
                                {
                                          setStatus(AuthenticationStatus.FAILURE);
                              log.info("Authentication failed for user '" + credentials.getUsername() + "'");            
                                }
                            }
                      
                      private void overrideRedirectFromLogin() {
                          
                          final String PRE_LOGIN_URL = LoginListener.class.getName() + "_PRE_LOGIN_URL";
                          final ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
                          final Map<String, Object> sessionMap = externalContext.getSessionMap();
                          String redirectURL = (String) sessionMap.get(PRE_LOGIN_URL);
                  
                  
                          if (redirectURL == null) {
                              final HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
                              redirectURL = request.getRequestURL().toString().replace("/login.html", "/view/home.html");
                              sessionMap.put(PRE_LOGIN_URL, redirectURL);
                          }
                      }    
                  
                  
                  }
                  
                  

                   

                  • 6. Re: seam 3 IllegalStateException after session timeout
                    Rahul Razdan Newbie

                    hi bob ,

                     

                    Thanks a lot !!

                     

                    it's a quick reply and i really appreciate it.

                     

                    Thanks again.

                    • 7. Re: seam 3 IllegalStateException after session timeout
                      Rahul Razdan Newbie

                      hi bob,

                       

                      Few Questions  :-

                       

                      1. while following this logic do i have to keep naviagtion related to login in faces-config.xml or i can remove them???

                      2. Did you find any correct fix for this or managing with the workaround only???

                       

                      Thanks

                      • 8. Re: seam 3 IllegalStateException after session timeout
                        Bob Shanahan Newbie

                        Hi Rahul,

                         

                        1. you can remove the faces-config.xml login nav rule

                        2. I've seen that Seam 3.1 has been released, but I have not updated the project. My app is still using the workaround.

                        • 9. Re: seam 3 IllegalStateException after session timeout
                          Rahul Razdan Newbie

                          hi bob,

                           

                          Thanks for the reply .

                          I'm using 3.1.FINAL , and this problem came so i don't think there is any fix yet.

                           

                          Thanks