2 Replies Latest reply on Oct 19, 2008 1:39 AM by pmuir

    Seam - Richfaces concurrency issue

    timgozag

      I posted this topic before but haven't resolved the problem. I reposted here with more details:


      Environment:JSF1.2, Seam2.0.2.SP1, RichFaces3.2.2.GA,Tomcat6.0.18


      We have a search page (see below) that when you hit Search (a4j:commandButton), it queries DB (using SerializationTestBean) and if the result returned too many records (more than 10), it will pop-up a Modal panel (Richface Modal Panel) asking if you'd like to Continue or Cancel. If you hit Continue, it will continue Searching and return all the records.


      We did Load testing on this apps using PureLoad. The test case is that each user hits Search button to return more than 10 records, then hits Continue button in Continue/Cancel Richfaces modal to perform the search.


      Tested many times for 10 concurrent users or more, it failed. BUT if I removed Richfaces Continue/Cancel Modal (do search dirrectly without questioning), it PASSED


      What did we do wrong and why it only happened to the Richfaces modal we integrate to the search page?




      Here is the track trace:




      Oct 16, 2008 5:46:43 PM com.sun.faces.lifecycle.Phase doPhase
      SEVERE: JSF1054: (Phase ID: RENDER_RESPONSE 6, View ID: /testSerialization.xhtml) Exception thrown during phase execution: javax.faces.event.
      PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl@e0de15]
      2008-10-16 17:46:43,733 ERROR *http-28650-19* ExceptionFilter.doFilter:68 [] handling uncaught exception
      javax.servlet.ServletException: null
              at javax.faces.webapp.FacesServlet.service(FacesServlet.java:277)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:522)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at com.expd.arch.webaccess.EIFilter.doFilter(EIFilter.java:80)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
              at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85)
              at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
              at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
              at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
              at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
              at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
              at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:177)
              at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:267)
              at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:380)
              at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:507)
              at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:60)
              at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
              at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
              at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
              at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
              at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
              at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
              at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:228)
              at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
              at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
              at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
              at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
              at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:216)
              at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
              at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:634)
              at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)
              at java.lang.Thread.run(Thread.java:595)
      Caused by: java.lang.IllegalArgumentException: null
              at javax.el.ListELResolver.coerce(ListELResolver.java:168)
              at javax.el.ListELResolver.getValue(ListELResolver.java:51)
              at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
              at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
              at org.jboss.el.parser.AstBracketSuffix.getValue(AstBracketSuffix.java:59)
              at org.jboss.el.parser.AstValue.getValue(AstValue.java:67)
              at org.jboss.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
              at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
              at org.jboss.el.parser.AstIdentifier.getValue(AstIdentifier.java:40)
              at org.jboss.el.parser.AstValue.getValue(AstValue.java:63)
              at org.jboss.el.parser.AstNotEqual.getValue(AstNotEqual.java:21)
              at org.jboss.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
              at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
              at javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:390)
              at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:276)
              at org.ajax4jsf.renderkit.RendererBase.renderChildren(RendererBase.java:262)
              at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:284)
              at org.richfaces.renderkit.AbstractRowsRenderer.encodeCellChildren(AbstractRowsRenderer.java:285)
              at org.richfaces.renderkit.AbstractTableRenderer.encodeOneRow(AbstractTableRenderer.java:361)
              at org.richfaces.renderkit.AbstractRowsRenderer.process(AbstractRowsRenderer.java:86)
              at org.ajax4jsf.model.SequenceDataModel.walk(SequenceDataModel.java:101)
              at org.ajax4jsf.component.UIDataAdaptor.walk(UIDataAdaptor.java:1151)
              at org.richfaces.renderkit.AbstractRowsRenderer.encodeRows(AbstractRowsRenderer.java:106)
              at org.richfaces.renderkit.AbstractRowsRenderer.encodeRows(AbstractRowsRenderer.java:91)
              at org.richfaces.renderkit.AbstractTableRenderer.encodeTBody(AbstractTableRenderer.java:73)
              at org.richfaces.renderkit.AbstractTableRenderer.encodeChildren(AbstractTableRenderer.java:80)
              at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:837)
              at javax.faces.component.UIComponent.encodeAll(UIComponent.java:936)
              at javax.faces.render.Renderer.encodeChildren(Renderer.java:148)
              at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:837)
              at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:282)
              at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:124)
              at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:67)
              at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:115)
              at org.ajax4jsf.renderkit.AjaxContainerRenderer.encodeAjax(AjaxContainerRenderer.java:123)
              at org.ajax4jsf.component.AjaxViewRoot.encodeAjax(AjaxViewRoot.java:677)
              at org.ajax4jsf.component.AjaxViewRoot.encodeChildren(AjaxViewRoot.java:548)
              at javax.faces.component.UIComponent.encodeAll(UIComponent.java:936)
              at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:592)
              at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:108)
              at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:196)
              at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:109)
              at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
              at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
              at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
              ... 36 more
      2008-10-16 17:46:43,737 ERROR *http-28650-19* ExceptionFilter.doFilter:69 [] exception root cause
      java.lang.IllegalArgumentException: null
      





      Here is SerializationTestBean




      @Name("serializationTestBean")
      @Scope(ScopeType.SESSION)
      public class SerializationTestBean implements Serializable{
              
              static private final int SHOW_MODAL_SIZE = 10;
              private String reference;
              private TabularDataSet dataSet;
              private List<Column> columns;
              private List<Row> rows;
              private boolean isTooLarge = false;
              private int page;
              
              public void search(ActionEvent ae) throws Exception {
                      this.dataSet = CannedDataStrategyImpl.getResultData(reference, 10);
              
                      this.isTooLarge = this.dataSet.size() > SHOW_MODAL_SIZE;
              }
      
              public void continueRendering() {
                      this.rows = new TabularDataSetList(this.dataSet);
                      this.columns = this.dataSet.getColumns();
              }
      
              public void cancelRendering(ActionEvent ae) {
                      this.dataSet = null;
                      this.rows = null;
                      this.columns = null;
              }
      
              public String getReference() {return reference; }
              public void setReference(String reference){this.reference= reference;}
              public List<Column> getColumns() {return this.columns;}
              public List<Row> getRows() {return this.rows;}
              public int getPage() {return page;}
              public void setPage(int page) {this.page = page;}
              public boolean isTooLarge()  {return this.isTooLarge;}
      }
      




      and here is the view:





      <ui:define name="pageTitle">#{messages.track_shipment_title}</ui:define>
         <ui:define name="pageBody">
                                              
            <h:form id="testSearchForm">
              <h:inputText value="#{serializationTestBean.reference}"/>
              <a4j:commandButton actionListener="#serializationTestBean.search}"
              value="Search"
             oncomplete="showTooLargeModal(#serializationTestBean.tooLarge});"/>
      
              <rich:dataTable id="resultsTable"
              value="#{serializationTestBean.rows}" 
              var="row" rows="20"
              rendered="#{null != serializationTestBean.rows}">
                              
            <rich:columns value="#{serializationTestBean.columns}" var="column" selfSorted="false"> 
              <f:facet name="header">
                <h:outputText value="#{column.header}"/>
              </f:facet>
                                                      
              <rp:resultsTableDataItem item="#row.items[column.index]}"/>
            </rich:columns>
                                              
              <f:facet name="footer">
              <rich:datascroller id="footerscroller" 
                 for="resultsTable"
                 page="#{serializationTestBean.page}" 
                 reRender="resultsTable"
                 rendered="#{rows != null}"
              status="ajaxStatus">
              
            </rich:datascroller>
              </f:facet>
              </rich:dataTable>
                              
           <rich:modalPanel id="tooLargeModal" width="350" height="100">
               <f:facet name="header">
             <h:panelGroup>
              <h:outputText value="#{messages.continue_or_cancel_label}">
              </h:outputText>
             </h:panelGroup>
               </f:facet>
                                    
             <div class="tooLargeModalTxt">#{messages.results_greater_than_continuable_threshold_message}</div>
      
             <a4j:commandButton  id="tooLargeModalSubmitBtn"
                styleClass="tooLargeModalSubmitBtn"
                value="#{messages.continue_button_label}" 
                action="#{serializationTestBean.continueRendering}"
                onclick="#{rich:component('tooLargeModal')}.hide();" 
                                                                              reRender="testSearchForm,resultsTable"/>
                                                                              
             <a4j:commandButton  value="#{messages.cancel_button_label}"  
              eventsQueue="tooLargeModalQueue"
              actionListener="#{serializationTestBean.cancelRendering}" 
              onclick="#{rich:component('tooLargeModal')}.hide()"  
              reRender="resultsTable"/>
                                                                              
          </rich:modalPanel>
              <script type="text/javascript">
               function showTooLargeModal(isTooLarge) {
              if (isTooLarge) {                                        
                     #{rich:component('tooLargeModal')}.show();}
               }      
              </script>
          </h:form>
        </ui:define>
      </ui:composition>



        • 1. Re: Seam - Richfaces concurrency issue
          timgozag

          Here is the area I think it cause the issue (it also helps people to understand the code I posted):


          In the View, when user click on Search button, it will invoke search() method in serializationTestBean. The search() method checks if the result is too large. If it is too large, the View calls a java script to show richfaces tooLargeModal


          <h:form id="testSearchForm">
            <h:inputText value="#{serializationTestBean.reference}"/>
            
            <a4j:commandButton  actionListener="#serializationTestBean.search}"
               value="Search"       oncomplete="showTooLargeModal(#serializationTestBean.tooLarge});"/>



               
          <script type="text/javascript">
                   function showTooLargeModal(isTooLarge) {
                  if (isTooLarge) {                                        
                         #{rich:component('tooLargeModal')}.show();}
                   }      
                  </script>
          



          The tooLargeModal is Richfaces modal as below:



               <rich:modalPanel id="tooLargeModal" width="350" height="100">
                   <f:facet name="header">
                 <h:panelGroup>
                  <h:outputText value="#{messages.continue_or_cancel_label}">
                  </h:outputText>
                 </h:panelGroup>
                   </f:facet>
                                        
                 <div class="tooLargeModalTxt">#{messages.results_greater_than_continuable_threshold_message}</div>
          
                 <a4j:commandButton  id="tooLargeModalSubmitBtn"
                    styleClass="tooLargeModalSubmitBtn"
                    value="#{messages.continue_button_label}" 
                    action="#{serializationTestBean.continueRendering}"
                    onclick="#{rich:component('tooLargeModal')}.hide();" 
                                                                                  reRender="testSearchForm,resultsTable"/>
                                                                                  
                 <a4j:commandButton  value="#{messages.cancel_button_label}"  
                  eventsQueue="tooLargeModalQueue"
                  actionListener="#{serializationTestBean.cancelRendering}" 
                  onclick="#{rich:component('tooLargeModal')}.hide()"  
                  reRender="resultsTable"/>
                                                                                  
              </rich:modalPanel>
          



          When user clicks on Continue button, it calls continueRendering() method in serializationTestBean to get data from DB:


           public void continueRendering() {
                 this.rows = new TabularDataSetList(this.dataSet);
                 this.columns = this.dataSet.getColumns();
            }
          



          ... then display on the view:


                  <rich:dataTable id="resultsTable"
                  value="#{serializationTestBean.rows}" 
                  var="row" rows="20"
                  rendered="#{null != serializationTestBean.rows}">
          



          That's when the concurrency errors occurred :(

          • 2. Re: Seam - Richfaces concurrency issue
            pmuir

            file an issue in the Seam JIRA with an example we can use to reproduce, we can take a look :-)