ICEfaces
  1. ICEfaces
  2. ICE-11024

ace:tree - ArrayIndexOutOfBoundsException thrown when expanding nodes

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Invalid
    • Affects Version/s: EE-3.3.0.GA_P03, 4.1.1
    • Fix Version/s: EE-4.1.0.GA, EE-3.3.0.GA_P04
    • Component/s: ACE-Components
    • Labels:
      None
    • Environment:
      All

      Description

      In this scenario, the tree nodes for the ace:tree are being built from a list of objects. When the tree is displayed an ArrayIndexOutOfBoundsException is thrown when expanding the 3rd level node.

      Looking at how the list is made for the nodes, everything seems to be fine and in the place where they should be.

      Partial stack trace:
      04-May-2016 14:52:51.508 SEVERE [http-nio-8084-exec-12] com.sun.faces.context.AjaxExceptionHandlerImpl.handlePartialResponseError java.lang.ArrayIndexOutOfBoundsException: -1
      at java.util.concurrent.CopyOnWriteArrayList.get(CopyOnWriteArrayList.java:368)
      at java.util.concurrent.CopyOnWriteArrayList.get(CopyOnWriteArrayList.java:377)
      at PlanNodeImpl.getChildAt(PlanNodeImpl.java:74)
      at org.icefaces.ace.model.tree.ListNodeDataModel.navToChild(ListNodeDataModel.java:127)
      at org.icefaces.ace.model.tree.ListNodeDataModel.navToChild(ListNodeDataModel.java:24)
      at org.icefaces.ace.component.tree.Tree.setNodeToChild(Tree.java:178)
      at org.icefaces.ace.component.tree.Tree.iterateTreeLevel(Tree.java:880)
      at org.icefaces.ace.component.tree.Tree.iterateTreeLevel(Tree.java:881)
      at org.icefaces.ace.component.tree.Tree.iterateTreeLevel(Tree.java:881)
      at org.icefaces.ace.component.tree.Tree.iterateTreeLevel(Tree.java:881)
      at org.icefaces.ace.component.tree.Tree.iterate(Tree.java:822)
      at org.icefaces.ace.component.tree.Tree.processValidators(Tree.java:348)
             ...
      1. ice11024-tree_test_2.png
        25 kB
      2. ice11024-tree_test.png
        18 kB

        Activity

        Hide
        Arran Mccullough added a comment -

        Attached test case and source code.

        To reproduce the exception:

        • Load welcomeICEfaces.jsf
        • Expand the nodes until the exception is thrown.
        Show
        Arran Mccullough added a comment - Attached test case and source code. To reproduce the exception: Load welcomeICEfaces.jsf Expand the nodes until the exception is thrown.
        Hide
        Arturo Zambrano added a comment -

        I made a custom test, based on the showcase. As seen in the screenshot, the nodes of the tree can be expanded to a very deep level with no issues. The markup in my test page is very similar to the one in the attached test case; the only difference is that my test tree doesn't use different different node types. I'll keep investigating to see if the type attribute has anything to do with the issue or if the problem is in the app code.

        Show
        Arturo Zambrano added a comment - I made a custom test, based on the showcase. As seen in the screenshot, the nodes of the tree can be expanded to a very deep level with no issues. The markup in my test page is very similar to the one in the attached test case; the only difference is that my test tree doesn't use different different node types. I'll keep investigating to see if the type attribute has anything to do with the issue or if the problem is in the app code.
        Hide
        Arturo Zambrano added a comment -

        I tested using different node types, and there are no issues, as seen in the second screenshot. I'll examine the implementation of the MutableTreeNode and the data factory of the test case to see if there is an issue there.

        Show
        Arturo Zambrano added a comment - I tested using different node types, and there are no issues, as seen in the second screenshot. I'll examine the implementation of the MutableTreeNode and the data factory of the test case to see if there is an issue there.
        Hide
        Arturo Zambrano added a comment - - edited

        I tried many different things including the following:

        • Integrating the attached test case code as is into the showcase app. The Exception didn't occur, and it was possible to expand the nodes to the deepest level. However, there was a slightly odd behaviour: the root nodes were duplicated, but only one of each pair could be expanded, and when expanding the deepest node; it only works for the second subtree, and both subtrees are expanded at the same time when this is done.
        • Integrating my own test tree into the attached test case and building from scratch. In this case, my test tree didn't show any issues and worked normally.
        • Copying all the context parameters from the web.xml in the showcase to the attached test case. This didn't make a difference.
        • Changing the use of CopyOnWriteArrayList in the factory class to regular ArrayList's. This didn't make a difference either.
        • Changing the use of arrays to ArrayLists in my own test tree (to see if the issue could be related to lists), but this didn't change anything; everything kept working normally.

        There doesn't seem to be an issue with the component code itself.

        In the end what made things work normally in the attached test case was to simply comment out the second add() call on the planList list, in the getSingleRoot() method of the PlanTreeDataFactory class. In this case, all the nodes could be expanded to the deepest level and there were no odd behaviours or exceptions.

        Most likely, the issue is in the PlanTreeDataFactory class itself, which uses a very convoluted approach to building the tree model. First of all, it uses iterators on various lists but also adds new elements to those very lists while iterating them, which is just not a good practice, even if taking thread-safe measures to avoid ConcurrentModificatonException's by using the CopyOnWriteArrayList class. The algorithm also seems to use separate lists for each node level/type and only allows one instance of each node with the same name/label. So, it seems like certain nodes can be shared between different roots. This is what caused the odd behaviour I was seeing that I describe in the first point above. I don't see the point in doing this. The node objects should be unique and only belong to one root. Multiple node objects could have a reference to the same data object, but the node objects should not be shared.

        I'm not familiar with the purpose of this application, but it certainly can be improved by using more standard patterns and best practices.

        I'm closing this issue as invalid for now.

        Show
        Arturo Zambrano added a comment - - edited I tried many different things including the following: Integrating the attached test case code as is into the showcase app. The Exception didn't occur, and it was possible to expand the nodes to the deepest level. However, there was a slightly odd behaviour: the root nodes were duplicated, but only one of each pair could be expanded, and when expanding the deepest node; it only works for the second subtree, and both subtrees are expanded at the same time when this is done. Integrating my own test tree into the attached test case and building from scratch. In this case, my test tree didn't show any issues and worked normally. Copying all the context parameters from the web.xml in the showcase to the attached test case. This didn't make a difference. Changing the use of CopyOnWriteArrayList in the factory class to regular ArrayList's. This didn't make a difference either. Changing the use of arrays to ArrayLists in my own test tree (to see if the issue could be related to lists), but this didn't change anything; everything kept working normally. There doesn't seem to be an issue with the component code itself. In the end what made things work normally in the attached test case was to simply comment out the second add() call on the planList list, in the getSingleRoot() method of the PlanTreeDataFactory class. In this case, all the nodes could be expanded to the deepest level and there were no odd behaviours or exceptions. Most likely, the issue is in the PlanTreeDataFactory class itself, which uses a very convoluted approach to building the tree model. First of all, it uses iterators on various lists but also adds new elements to those very lists while iterating them, which is just not a good practice, even if taking thread-safe measures to avoid ConcurrentModificatonException's by using the CopyOnWriteArrayList class. The algorithm also seems to use separate lists for each node level/type and only allows one instance of each node with the same name/label. So, it seems like certain nodes can be shared between different roots. This is what caused the odd behaviour I was seeing that I describe in the first point above. I don't see the point in doing this. The node objects should be unique and only belong to one root. Multiple node objects could have a reference to the same data object, but the node objects should not be shared. I'm not familiar with the purpose of this application, but it certainly can be improved by using more standard patterns and best practices. I'm closing this issue as invalid for now.

          People

          • Assignee:
            Arturo Zambrano
            Reporter:
            Arran Mccullough
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: