2 Replies Latest reply on Nov 28, 2007 5:38 PM by jeffzzang

    NullPointerException when removing node in tree

    jeffzzang

      I am using <rich:tree > with a few nested <rich:treeNodesAdaptors> and when I remove one of the nodes from the tree and then re-render the tree, I get the following exception:

      java.lang.NullPointerException
      at org.richfaces.model.StackingTreeModel.walk(StackingTreeModel.java:361)
      at org.richfaces.model.StackingTreeModel.walkModel(StackingTreeModel.java:457)
      at org.richfaces.component.UITree.walkModel(UITree.java:357)
      at org.richfaces.component.state.TreeState.visitNodes(TreeState.java:200)
      at org.richfaces.component.state.TreeState.expandNode(TreeState.java:262)
      at org.richfaces.component.state.events.ExpandNodeCommandEvent.execute(ExpandNodeCommandEvent.java:48)
      at org.richfaces.component.state.events.TreeStateCommandEvent.processListener(TreeStateCommandEvent.java:59)
      at org.richfaces.component.UITree.broadcast(UITree.java:489)
      at org.ajax4jsf.component.UIInclude.broadcast(UIInclude.java:138)
      at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:184)
      at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:162)
      at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:350)
      at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.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 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)
      at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:147)
      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:233)
      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:102)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
      at java.lang.Thread.run(Unknown Source)

      The way I remove it is to see which "row" was removed, remove it from the underlying collection, and then repopulate the underlying Collection for the outer-most treeNodesAdaptor. Anyone have any ideas?

        • 1. Re: NullPointerException when removing node in tree
          jeffzzang

          Update:

          I've also come across the following exception when adding nodes to the tree. Also note, this only happens if I add nodes in certain places.

          java.lang.IllegalStateException
          at org.richfaces.model.StackingTreeModel.getInternalModelById(StackingTreeModel.java:337)
          at org.richfaces.model.StackingTreeModel.doSetupKey(StackingTreeModel.java:134)
          at org.richfaces.model.StackingTreeModel.doSetupKey(StackingTreeModel.java:150)
          at org.richfaces.model.StackingTreeModel.doSetupKey(StackingTreeModel.java:150)
          at org.richfaces.model.StackingTreeModel.setupKey(StackingTreeModel.java:171)
          at org.richfaces.model.StackingTreeModel.setRowKey(StackingTreeModel.java:470)
          at org.ajax4jsf.component.UIDataAdaptor.setRowKey(UIDataAdaptor.java:319)
          at org.ajax4jsf.component.UIDataAdaptor.setRowKey(UIDataAdaptor.java:299)
          at org.richfaces.renderkit.TreeRendererBase.encodeSelectionStateInput(TreeRendererBase.java:547)
          at org.richfaces.renderkit.html.TreeRenderer.doEncodeEnd(TreeRenderer.java:216)
          at org.richfaces.renderkit.html.TreeRenderer.doEncodeEnd(TreeRenderer.java:239)
          at org.ajax4jsf.renderkit.RendererBase.encodeEnd(RendererBase.java:135)
          at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:539)
          at javax.faces.component.UIData.encodeEnd(UIData.java:573)
          at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:286)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:143)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:86)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:134)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:86)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:134)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:86)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:134)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:86)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:134)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:86)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:134)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:86)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:134)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:86)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:134)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:86)
          at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:134)
          at org.ajax4jsf.renderkit.AjaxContainerRenderer.encodeAjax(AjaxContainerRenderer.java:122)
          at org.ajax4jsf.component.UIAjaxRegion.encodeAjax(UIAjaxRegion.java:239)
          at org.ajax4jsf.context.AjaxContextImpl.renderAjaxRegion(AjaxContextImpl.java:289)
          at org.ajax4jsf.context.AjaxContextImpl$2.invoke(AjaxContextImpl.java:204)
          at org.ajax4jsf.context.JsfOneOneInvoker.invokeOnComponent(JsfOneOneInvoker.java:78)
          at org.ajax4jsf.context.JsfOneOneInvoker.invokeOnComponent(JsfOneOneInvoker.java:83)
          at org.ajax4jsf.context.JsfOneOneInvoker.invokeOnComponent(JsfOneOneInvoker.java:83)
          at org.ajax4jsf.context.JsfOneOneInvoker.invokeOnComponent(JsfOneOneInvoker.java:83)
          at org.ajax4jsf.context.JsfOneOneInvoker.invokeOnComponent(JsfOneOneInvoker.java:83)
          at org.ajax4jsf.context.JsfOneOneInvoker.invokeOnComponent(JsfOneOneInvoker.java:83)
          at org.ajax4jsf.context.AjaxContextImpl.invokeOnComponent(AjaxContextImpl.java:160)
          at org.ajax4jsf.context.AjaxContextImpl.renderSubmittedAjaxRegion(AjaxContextImpl.java:218)
          at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:239)
          at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:41)
          at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:132)
          at javax.faces.webapp.FacesServlet.service(FacesServlet.java:140)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)
          at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)
          at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
          at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
          at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:147)
          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:233)
          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:102)
          at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
          at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
          at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
          at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
          at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
          at java.lang.Thread.run(Unknown Source)

          It looks like in the StackingTreeModel class, the error is being thrown here:

          private StackingTreeModel getInternalModelById(String id) {
          StackingTreeModel model = getModelById(id);
          if (model.isActive()) {
          return model;
          }

          throw new IllegalStateException();
          }

          As you can see, the IllegalStateException only gets thrown if model.isActive() return false. If we look at the isActive() method:

          protected boolean isActive() {
          return true;
          }

          so how is this happening? I looked through the source and didn't find any subclasses of the StackingTreeModel that overrode isActive. Any thoughts?

          • 2. Re: NullPointerException when removing node in tree
            jeffzzang

            I think I figured it out. I think what's happening is when you use switchType="client" the view tries to rebuild the tree locally (and expand/collapse the appropriate levels), and it chokes because I just removed one of the rows from the tree and it tries to expand that node I just removed. The reason I suspect this is because when I add/remove elements to the tree, it sometimes expanded/collapsed the wrong levels.

            I tried changing it to switchType="ajax" and it works, but this is not desirable as a roundtrip to the server is not really necessary for expanding and collapsing nodes.

            The one other modification I had to perform was to call reRender on the <h:panelGrid/> that surrounded the <rich:tree/>. I've noticed this in other places as well, can someone explain this to me?

            For example:

            <h:panelGrid columns="1" id="scheduleTreePanel">
             <rich:tree id="scheduleTree" switchType="ajax" preserveModel="none" immediate="false" toggleOnClick="true">
             <rich:treeNodesAdaptor nodes="#{controller.scheduleNodes}" var="treeDates">
             <a4j:commandLink actionListener="#{controller.removeOtherEvent}" reRender="scheduleTree" >
             <h:outputText value="Remove"/>
             </a4j:commandLink>
             </rich:treeNodesAdaptor>
             </rich:tree>
            </h:panelGrid>
            


            If I have reRender="scheduleTree" as I have above, the code breaks. If, however, I set reRender to "scheduleTreePanel", it magically works. Anyone know what's going on?