10 Replies Latest reply on Aug 12, 2010 3:02 PM by wangliyu

    Exception when ending Conversation with Post-Redirect-Get?

    wangliyu
      I found a very weird exception when ending Conversation with Post-Redirect-Get method (the old Seam2 "standard way" to end conversation):

      Here is the full trace:

      INFO: ConversationTester: destroy: ID: 3, transient: false, timeout: 600000ms
      INFO: >>> getNavigationCase
      INFO: >>>>> test navigation case: #{resetSession.reset()}:home?faces-redirect=true : NavigationCase{fromViewId='/', fromAction='#{resetSession.reset()}', fromOutcome='home?faces-redirect=true', if='null', toViewId='/home.xhtml', faces-redirect=true, includeViewParams=false', parameters=}
      INFO:   <== after phase: INVOKE_APPLICATION 5, view ID:/home.xhtml
      WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
      org.jboss.weld.context.NonexistentConversationException: WELD-000301 Could not restore long-running conversation 3 because id not known
              at org.jboss.weld.conversation.AbstractConversationManager.beginOrRestoreConversation(AbstractConversationManager.java:107)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:304)
              at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:54)
              at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:163)
              at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:298)
              at org.jboss.weld.bean.proxy.ClientProxyMethodHandler.invoke(ClientProxyMethodHandler.java:113)
              at org.jboss.weld.util.CleanableMethodHandler.invoke(CleanableMethodHandler.java:43)
              at org.jboss.weld.conversation.ServletConversationManager_$$_javassist_2.beginOrRestoreConversation(ServletConversationManager_$$_javassist_2.java)
              at org.jboss.weld.jsf.WeldPhaseListener.initiateSessionAndConversation(WeldPhaseListener.java:171)
              at org.jboss.weld.jsf.WeldPhaseListener.beforeRestoreView(WeldPhaseListener.java:118)
              at org.jboss.weld.jsf.WeldPhaseListener.beforePhase(WeldPhaseListener.java:87)
              at com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:228)
              at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:99)
              at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:110)
              at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
              at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)


      Did anybody find same issue?
        • 1. Re: Exception when ending Conversation with Post-Redirect-Get?
          nickarls

          It looks like the conversation is ended but the cid=3 is propagated and can't be restored

          • 2. Re: Exception when ending Conversation with Post-Redirect-Get?
            wangliyu

            Yes, It seems the conversation stored in the same place with SessionContext object, and if session invalid, CDI does cleanup the Conversation context, but the conversation is still alive. and when redirect, the CDI try to restore an invalid context, and that's cause the problem. I'm looking into AbstractConversationManager.cleanupConversation(), it seems that I have to explicit call Conversation.end() before HttpSession.invalid().

            • 3. Re: Exception when ending Conversation with Post-Redirect-Get?
              wangliyu

              It surprised me, the Conversation is not bound with Session Scope but it share the same place with Session Scope, so if I invalid session scope before call conversation.end(), it won't change the conversation status to transient, but the actual context is already gone, that's cause the exception, so if I need to invalid session (for example logout the user), I have to manually call conversation.end() before call HttpSession.invalid().


              This is different than Seam2.x. Is this a bug or a undocument exception?

              • 4. Re: Exception when ending Conversation with Post-Redirect-Get?
                nickarls

                Could you file a JIRA with a small test case so we can iron it out?

                • 5. Re: Exception when ending Conversation with Post-Redirect-Get?
                  nickarls

                  BTW, can you try in trunk as the conversation setup/teardown might be occurring at another place (servlet listener) there?

                  • 6. Re: Exception when ending Conversation with Post-Redirect-Get?
                    wangliyu

                    I still can't get the JIRA password reset (it said I should get email but I didn't and it tells me have to wait another 24 hours...), Anyway, it's very easy to produce this, you can try it, create with maven archetype:



                    -DarchetypeArtifactId=weld-jsf-servlet-minimal
                    -DarchetypeGroupId=org.jboss.weld.archetypes





                    add following new class:




                    @RequestScoped
                    @Named("lifecycleTester")
                    public class ConversationLifecycleTest {
                    
                        @Inject
                        private Conversation conversation;
                        @Inject
                        private HttpSession session;
                    
                        public String logout() {
                            if (conversation.isTransient()) {
                                System.out.println("begin the LRC here.");
                                conversation.begin();
                            }
                            System.out.println("about to invalid the session here." + session.getId());
                            session.invalidate();
                            return "home?faces-redirect=true";
                        }
                    }



                    and change the line in the home.xhtml:




                    <h:commandButton id="check" action="#{lifecycleTester.logout}" value="Check values"/>



                    run with TC6 or GF3, should see the exception:




                    INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
                    INFO: HelloWorld was constructed
                    INFO: begin the LRC here.
                    INFO: about to invalid the session here.
                    WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
                    org.jboss.weld.context.NonexistentConversationException: WELD-000301 Could not restore long-running conversation 2 because id not known
                            at org.jboss.weld.conversation.AbstractConversationManager.beginOrRestoreConversation(AbstractConversationManager.java:107)
                            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                            at java.lang.reflect.Method.invoke(Method.java:597)
                            at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:304)
                            at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:54)
                            at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:163)
                            at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:298)
                            at org.jboss.weld.bean.proxy.ClientProxyMethodHandler.invoke(ClientProxyMethodHandler.java:113)
                            at org.jboss.weld.util.CleanableMethodHandler.invoke(CleanableMethodHandler.java:43)
                            at org.jboss.weld.conversation.ServletConversationManager_$$_javassist_3.beginOrRestoreConversation(ServletConversationManager_$$_javassist_3.java)
                            at org.jboss.weld.jsf.WeldPhaseListener.initiateSessionAndConversation(WeldPhaseListener.java:171)
                            at org.jboss.weld.jsf.WeldPhaseListener.beforeRestoreView(WeldPhaseListener.java:118)
                            at org.jboss.weld.jsf.WeldPhaseListener.beforePhase(WeldPhaseListener.java:87)
                            at com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:228)
                            at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:99)
                            at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:110)
                            at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
                            at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
                            at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
                            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
                            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
                            at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
                            at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
                            at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
                            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
                            at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
                            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
                            at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
                            at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
                            at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
                            at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
                            at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
                            at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
                            at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
                            at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
                            at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
                            at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
                            at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
                            at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
                            at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
                            at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
                            at java.lang.Thread.run(Thread.java:619)
                    
                    
                    




                    and if you add




                    if(!conversation.isTransient())
                                conversation.end();





                    before
                           


                    session.invalidate();




                    you will not be able to get any exception.







                    • 7. Re: Exception when ending Conversation with Post-Redirect-Get?
                      wangliyu

                      It's good news to see the conversation no long bundle with JSF phase listener, I'll definitely try the trunk, one question though, In my mind, the Dependent Context, Request Context, Conversation Context, Session Context should be created and destroyed at the same spot, the only difference is their life spans, RequestContext, DependentContext and transient conversation will be create and destroy only for one request, LRC will be keep until it turns to transient conversation or session invalid, SessionContext will be destroyed after session.invalid or session timeout. I'm not sure if this is the right or I'm missing something?

                      • 8. Re: Exception when ending Conversation with Post-Redirect-Get?
                        nickarls

                        I'm not sure what you're saying ;-)


                        Session context items survive multiple request because they are stored in the HTTP session and for every request, the ThreadLocal BeanStore is restored with the users session as backing data store. The session scope actually survives session destruction until the end of the request due to some buffering (as required by the spec).


                        A wrote a bit on the subject here

                        • 9. Re: Exception when ending Conversation with Post-Redirect-Get?
                          wangliyu

                          So even if I call HttpSession.invalidation() it should cleanup the session context objects and conversation context objects after the request destroyed?


                          BTW, I have tested with the new version (kind lazy, just downloaded the Hudson night build) and test result is same.

                          • 10. Re: Exception when ending Conversation with Post-Redirect-Get?
                            wangliyu

                            Ticket created: My Link