0 Replies Latest reply on Sep 15, 2009 11:18 AM by Josh Earel

    Expanding 2 large trees at once causes NPE

    Josh Earel Newbie

      We 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?