Expanding 2 large trees at once causes NPE
khisanthmagus Sep 15, 2009 11:18 AMWe are currently using richfaces 3.1.5 in our application due to limitations of the server(OC4J server).
We have a page in our application that has 2 instances of the rich:tree component, both with the same backing data. They are defined as:
<rich:tree id="itemGroupTreeSource" value="#{ItemGroup.treeNode}" var="groups" showConnectingLines="true" ajaxSubmitSelection="true" reRender="dataTable" nodeFace="#{groups.type}" selectedClass="treeNodeSelectedText"> <rich:treeNode type="disabled" iconLeaf="/images/iconFolderDisabled.GIF" icon="/images/iconFolderDisabled.GIF"> <h:outputText value="#{groups.group.itemGroupName}" styleClass="treeNodeNotAllowed" /> </rich:treeNode> <rich:treeNode type="node" nodeSelectListener="#{assetMoveAction.onSourceTreeClick}" iconLeaf="/images/iconFolder.gif" icon="/images/iconFolder.gif"> <h:outputText value="#{groups.group.itemGroupName}" /> </rich:treeNode> <rich:treeNode type="root" nodeSelectListener="#{assetMoveAction.onSourceTreeClick}" iconLeaf="/images/iconFolder.gif" icon="/images/iconFolder.gif"> <h:outputText value="#{groups.group.itemGroupName}" /> </rich:treeNode> <rich:treeNode type="testPackage" nodeSelectListener="#{assetMoveAction.onSourceTreeClick}" iconLeaf="/images/iconFolder.gif" icon="/images/iconFolder.gif"> <h:outputText value="#{groups.group.itemGroupName}"/> </rich:treeNode> <%if(canSelectRecycleBin){%> <rich:treeNode type="recycle" nodeSelectListener="#{assetMoveAction.onSourceTreeClick}" iconLeaf="/images/recyclebin.gif" icon="/images/recyclebin.gif"> <h:outputText value="#{groups.group.itemGroupName}" /> </rich:treeNode> <%}else{%> <rich:treeNode type="recycle" iconLeaf="/images/recyclebin_disabled.gif" icon="/images/recyclebin_disabled.gif"> <h:outputText value="#{groups.group.itemGroupName}" styleClass="treeNodeNotAllowed" /> </rich:treeNode> <%}%> </rich:tree>
and
<rich:tree id="itemGroupTreeDestination" value="#{ItemGroup.treeNode}" var="groups" showConnectingLines="true" ajaxSubmitSelection="true" nodeFace="#{groups.type}" selectedClass="treeNodeSelectedText"> <rich:treeNode type="disabled" iconLeaf="/images/iconFolderDisabled.GIF" icon="/images/iconFolderDisabled.GIF"> <h:outputText value="#{groups.group.itemGroupName}" styleClass="treeNodeNotAllowed" /> </rich:treeNode> <rich:treeNode type="node" nodeSelectListener="#{assetMoveAction.onDestinationTreeClick}" iconLeaf="/images/iconFolder.gif" icon="/images/iconFolder.gif"> <h:outputText value="#{groups.group.itemGroupName}" /> </rich:treeNode> <rich:treeNode type="root" nodeSelectListener="#{assetMoveAction.onDestinationTreeClick}" iconLeaf="/images/iconFolder.gif" icon="/images/iconFolder.gif"> <h:outputText value="#{groups.group.itemGroupName}" /> </rich:treeNode> <rich:treeNode type="testPackage" iconLeaf="/images/iconFolder.gif" icon="/images/iconFolder.gif" nodeSelectListener="#{assetMoveAction.onDestinationTreeClick}"> <h:outputText value="#{groups.group.itemGroupName}"/> </rich:treeNode> <%if(canSelectRecycleBin){%> <rich:treeNode type="recycle" nodeSelectListener="#{assetMoveAction.onDestinationTreeClick}" iconLeaf="/images/recyclebin.gif" icon="/images/recyclebin.gif"> <h:outputText value="#{groups.group.itemGroupName}" /> </rich:treeNode> <%}else{%> <rich:treeNode type="recycle" iconLeaf="/images/recyclebin_disabled.gif" icon="/images/recyclebin_disabled.gif"> <h:outputText value="#{groups.group.itemGroupName}" styleClass="treeNodeNotAllowed" /> </rich:treeNode> <%}%> </rich:tree>
It is possible for the data in these trees to get very large and take several seconds to expand a node. If the data being loaded when a node is being expanded is large enough, you can get a NullPointerException if you attempt to expand the second tree while the first is still expanding. This is the error:
javax.faces.FacesException: java.lang.NullPointerException at org.ajax4jsf.component.UIDataAdaptor.iterate(UIDataAdaptor.java:978) at org.ajax4jsf.component.UIDataAdaptor.processDecodes(UIDataAdaptor.java:1001) at org.richfaces.component.UITree.processDecodes(UITree.java:450) at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:605) at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:605) at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:605) at javax.faces.component.UIForm.processDecodes(UIForm.java:56) at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:605) at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:605) at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:605) at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:138) at org.ajax4jsf.component.AjaxViewRoot.access$001(AjaxViewRoot.java:57) at org.ajax4jsf.component.AjaxViewRoot$1.invokeRoot(AjaxViewRoot.java:260) at org.ajax4jsf.context.JsfOneOneInvoker.invokeOnRegionOrRoot(JsfOneOneInvoker.java:56) at org.ajax4jsf.context.AjaxContextImpl.invokeOnRegionOrRoot(AjaxContextImpl.java:170) at org.ajax4jsf.component.AjaxViewRoot.processDecodes(AjaxViewRoot.java:276) at org.apache.myfaces.lifecycle.ApplyRequestValuesExecutor.execute(ApplyRequestValuesExecutor.java:32) at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:95) at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:70) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:139) at com.evermind.server.http.ResourceFilterChain.doFilter(ResourceFilterChain.java:64) at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:100) at com.evermind.server.http.EvermindFilterChain.doFilter(EvermindFilterChain.java:15) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at com.evermind.server.http.EvermindFilterChain.doFilter(EvermindFilterChain.java:17) at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141) at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281) at com.evermind.server.http.EvermindFilterChain.doFilter(EvermindFilterChain.java:17) at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:190) at com.evermind.server.http.EvermindFilterChain.doFilter(EvermindFilterChain.java:17) at org.act.idmp.filter.LocaleFilter.doFilter(LocaleFilter.java:60) at com.evermind.server.http.EvermindFilterChain.doFilter(EvermindFilterChain.java:17) at org.act.idmp.filter.RequestControlFilter.doFilter(RequestControlFilter.java:161) at com.evermind.server.http.EvermindFilterChain.doFilter(EvermindFilterChain.java:17) at org.act.idmp.filter.SecurityFilter.doFilter(SecurityFilter.java:210) at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:627) at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:376) at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.java:870) at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:451) at com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.java:299) at com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.java:187) at oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.java:260) at oracle.oc4j.network.ServerSocketAcceptHandler.procClientSocket(ServerSocketAcceptHandler.java:230) at oracle.oc4j.network.ServerSocketAcceptHandler.access$800(ServerSocketAcceptHandler.java:33) at oracle.oc4j.network.ServerSocketAcceptHandler$AcceptHandlerHorse.run(ServerSocketAcceptHandler.java:831) at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303) at java.lang.Thread.run(Thread.java:595) Caused by: java.lang.NullPointerException at org.richfaces.component.state.TreeState$3.processNode(TreeState.java:267) at org.richfaces.model.TreeDataModel.doWalk(TreeDataModel.java:70) at org.richfaces.model.TreeDataModel.walk(TreeDataModel.java:139) at org.richfaces.component.CacheableTreeDataModel.walk(CacheableTreeDataModel.java:123) at org.richfaces.model.AbstractTreeDataModel.walk(AbstractTreeDataModel.java:66) at org.ajax4jsf.component.UIDataAdaptor.walk(UIDataAdaptor.java:994) at org.ajax4jsf.component.UIDataAdaptor.iterate(UIDataAdaptor.java:976) ... 47 more
I can't think of any way to prevent this. Anyone have any advice on how to prevent this?