Seam - Richfaces concurrency issue
timgozag Oct 17, 2008 1:07 AMI 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>