3 Replies Latest reply on Jul 20, 2007 5:02 PM by chubinator

    Conversation Timeout and Redirect

    chubinator

      Hello,

      We are currently using Seam 1.2.1.GA and I have a question regarding the conversation time outs and redirects.

      We have a page called listcontacts.xhtml with an s:link that calls a bean method action:

      <s:link action="#{contactBean.add}" styleClass="button">Add</s:link>
      


      This method is annotated with the @Begin annotation:

       @Begin
       public void add() {
       contact = new Contact();
       }
      


      The contact is outjected:
       @In(required=false)
       @Out(required=false)
       private Contact contact;
      


      In our pages.xml, we have:

       <page view-id="/secure/*" scheme="https">
       <navigation from-action="#{contactBean.add}">
       <redirect view-id="/secure/editcontact.xhtml" />
       </navigation>
       ...
      


      When we log into our app and click this link, it works as expected and takes us to our editcontact.xhtml page with the new blank contact.

      If we wait 2 minutes (our conversation timeout length), and then click the link, we get the following error:

      21:22:37,812 ERROR [STDERR] Jul 19, 2007 9:22:37 PM com.sun.facelets.FaceletViewHandler handleRenderException
      SEVERE: Error Rendering View[/secure/editcontact.xhtml]
      javax.faces.el.PropertyNotFoundException: /secure/editcontact.xhtml @28,91 value="#{contact.contactType}": Target Unreachable, i
      dentifier 'contact' resolved to null
       at com.sun.facelets.el.LegacyValueBinding.getType(LegacyValueBinding.java:96)
       at org.jboss.seam.ui.EnumItem.getValue(EnumItem.java:47)
       at org.apache.myfaces.shared_impl.util.SelectItemsIterator.hasNext(SelectItemsIterator.java:70)
       at org.apache.myfaces.shared_impl.renderkit.RendererUtils.internalGetSelectItemList(RendererUtils.java:477)
       at org.apache.myfaces.shared_impl.renderkit.RendererUtils.getSelectItemList(RendererUtils.java:453)
       at org.apache.myfaces.shared_impl.renderkit.html.HtmlRendererUtils.internalRenderSelect(HtmlRendererUtils.java:278)
       at org.apache.myfaces.shared_impl.renderkit.html.HtmlRendererUtils.renderMenu(HtmlRendererUtils.java:252)
       at org.apache.myfaces.shared_impl.renderkit.html.HtmlMenuRendererBase.encodeEnd(HtmlMenuRendererBase.java:54)
       at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:536)
       at org.jboss.seam.ui.JSF.renderChild(JSF.java:180)
       at org.jboss.seam.ui.JSF.renderChildren(JSF.java:162)
       at org.jboss.seam.ui.UIDecorate.encodeChildren(UIDecorate.java:234)
       at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:244)
       at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:249)
       at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:249)
       at com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:249)
       at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:573)
       at org.ajax4jsf.framework.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:108)
       at org.ajax4jsf.framework.ajax.AjaxViewHandler.renderView(AjaxViewHandler.java:229)
       at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:384)
       at javax.faces.webapp.FacesServlet.service(FacesServlet.java:138)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:63)
       at org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:60)
       at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
       at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
       at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
       at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:57)
       at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
       at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:79)
       at org.jboss.seam.web.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:49)
       at org.jboss.seam.web.SeamFilter.doFilter(SeamFilter.java:84)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.ajax4jsf.framework.ajax.xmlfilter.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:96)
       at org.ajax4jsf.framework.ajax.xmlfilter.BaseFilter.doFilter(BaseFilter.java:220)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
       at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
       at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
       at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
       at java.lang.Thread.run(Thread.java:595)
      


      Looking at the DEBUG entries, it appears as though a conversation cleanup occurs after the add method exits, but before the @Begin is applied and the conversation is promoted to long running.

      If I replace the redirect with render, it works...at least until it hits another redirect.

      Why would redirect behave differently after a conversation timeout? Shouldn't the temporary conversation be promoted to a long running before the redirect and thus everything should work?

      Why would it work before the timeout but not after.

      Any help is greatly appreciated.

      Thanks,
      Mark

        • 1. Re: Conversation Timeout and Redirect
          chubinator

          Ok, I think I understand the problem:

          1. @Begin does not start a new conversation until after the method completes.

          2. Thus, the object I created in the method was actually outjected to the "current" conversation.

          3. The conversation time out is not enforced until just prior to the redirect. So the "current" conversation is the one thats about to be timed out.

          4. My outjected variable is destroyed when the "current" conversation is timed out.

          5. I get a new (long running) conversation just prior to my redirect as well, one without my outjected variable.

          I guess what confuses me now is why doesn't seam either:

          a. avoid outjecting to a soon to be timed out conversations.

          or

          b. Allow the promotion of soon to be timed out conversations to long running conversations and skip the timeout. Although I can see this still being a problem for cases where you just want to use the temporary conversation.



          • 2. Re: Conversation Timeout and Redirect
            chubinator

            The more I look at this, the more I'm starting to think this is a bug.

            I removed my @Begin figuring I can just rely on the temporary conversation. Its my understanding that I should have a temporary conversation across the request and reply.

            But even without the @Begin, I get the same error after a conversation timeout.

            It really seems to me that the timeouts should be applied as early as possible and that the outjection should be to the new temporary conversation.

            Or, I could be way off...

            • 3. Re: Conversation Timeout and Redirect
              chubinator

               

              Or, I could be way off...


              Lets go with that.

              After digging deeper, I found that before navigating to the page in question (listcontacts.xhtml), the page I was navigating from started a new conversation using @Begin in combination with @Create. Worse, it used @End with its @Destroy method.

              So the problem wasn't so much the timeout as much as when it cleaned up the previous bean (used for the previous page), it found the @End and likely ended the current conversation as well.

              I'm not sure where I saw this @Destroy/@End combo, but I'm thinking I should avoid doing that as I would imagine the behavior is unpredictable.

              Sorry for the false alarm.