0 Replies Latest reply on Aug 24, 2007 9:24 PM by Paul Pantages

    Ajax race condition causes Conversation.flush NPE

    Paul Pantages Novice

      SEAM 1.2.1 GA
      Ajax - 1.1.1-SNAPSHOT (from seam dist)

      Hello forum,

      I have finally a clue about my Conversation.flush() errors. This is due to a race condition between my ajax poll and my @End method, which is called when the user presses apply/cancel.

      I am able to reproduce this reliably by:

      (1) Starting a nested conversation, from a long running conversation.
      (2) I poll the corresponding backing bean, with reRender="#{bean1.ajaxRenderList}"
      (3) I End the conversation with a button action="#{bean1.apply}"
      (4) Stick a Thread.sleep() in apply() to stall it for 4s
      (5) Use a 2s interval on the poll to ensure it fires during an apply() call

      What I think happens is:
      - After I press apply, the poller attempts to access the bean "at the same time"
      - Since the bean is @Synchronized, this call has to wait.
      - When apply() finishes, Seam cleans up the conversation as per @End
      - When the poll thread runs, tries to access the component, causing the flush() error due to an inconsistent state.

      With the Thread.sleep() the error is reproducible every time.

      So... Does anyone know of a good way to synchrhonize these actions (poll + command button) and avoid this problem? I would like to be able to do this on the server-side if possible.

      Any ideas would be appreciated.

      fyi, My beans are like so:

      @Stateful
      @Scope(CONVERSATION)
      @LoggedIn
      @Synchronized
      @Conversational
      @Name("bean1")
      public class Bean1 implements Bean1Local {
      
      @Begin(nested=true)
      public String edit () {
       return "page1";
      }
      ...
      
      @End
      public String apply () {
      
       // Delay, so that poller will come in before we are done.
       Thread.sleep (4000);
      
       return "page2";
      
      }
      
      public String getAjaxRenerList () {
       return "a4jPanel1";
      }
      
      


      <a4j:region id="pollRegion" renderRegionOnly="false">
       <a4j:poll
       id="poller"
       interval="2000"
       enabled="true"
       eventsQueue="pollerQueue"
       reRender="#{bean1.ajaxRenderList}">
       </a4j:poll>
      </a4j:region>
      

      java.lang.NullPointerException
       at org.jboss.seam.core.Conversation.flush(Conversation.java:122)
       at org.jboss.seam.core.Manager.prepareBackswitch(Manager.java:1165)
      
       at org.jboss.seam.jsf.AbstractSeamPhaseListener.beforeRender(AbstractSeamPhaseListener.java:229)
       at org.jboss.seam.jsf.SeamPhaseListener.beforePhase(SeamPhaseListener.java:56)
       at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersBefore(PhaseListenerManager.java:70)
       at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:373)
       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.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:147)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:57)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
       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.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:524)
       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)
      2007-08-23 19:16:29,615 ERROR [http-0.0.0.0-8080-2] org.jboss.seam.jsf.SeamPhaseListener
      swallowing exception