ICEfaces
  1. ICEfaces
  2. ICE-2206

Tree tag requires a single child treeNode tag exception

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Invalid
    • Affects Version/s: 1.6.1
    • Fix Version/s: 1.6.2
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      all

      Description

      When having both a value and component binding on a tree component, a user will often encounter a 'tree tag requires a single child treeNode tag' exception. The page containing the tree will render correctly the first time, but if a refresh is done on the page, or a simple navigation is done from that page back to itself, the exception will be thrown. I have attached a test case which is our basic tree component along with a simple binding.

        Activity

        Hide
        Tyler Johnson added a comment -

        Forgot to attach test case. Refresh the page or click the navigate button.

        Show
        Tyler Johnson added a comment - Forgot to attach test case. Refresh the page or click the navigate button.
        Hide
        Adnan Durrani added a comment -

        With the attached tested case this problem can be reproduced. The problem happens only if the scope of the bean which binds the tree is "session" and the "com.icesoft.faces.concurrentDOMViews" is set to "true".

        Show
        Adnan Durrani added a comment - With the attached tested case this problem can be reproduced. The problem happens only if the scope of the bean which binds the tree is "session" and the "com.icesoft.faces.concurrentDOMViews" is set to "true".
        Hide
        Adnan Durrani added a comment -

        The page refresh causes the executeJspLifeCycle() to be executed. Which I guess suppose to create a fresh component tree, but it seems like when the concurrentDOMViews is true and the bean scope is set to the session, ICEfaces uses the old "Tree" component instance which already had a child (TreeNode) and the executeJspLifeCycle() on the page refresh creates another child node to the existing Tree component, which already had a child.

        That means on page refresh Tree component gets two child nodes and there is a case in the TreeRenderer that it can have only one children, but after page refresh there are two, that is why the TreeRenderer throws the following exception.

        com.icesoft.faces.component.tree.MalformedTreeTagException: The tree tag requires a single child treeNode tag. Found [2]
        com.icesoft.faces.component.tree.TreeRenderer.encodeBegin(TreeRenderer.java:146)

        Show
        Adnan Durrani added a comment - The page refresh causes the executeJspLifeCycle() to be executed. Which I guess suppose to create a fresh component tree, but it seems like when the concurrentDOMViews is true and the bean scope is set to the session, ICEfaces uses the old "Tree" component instance which already had a child (TreeNode) and the executeJspLifeCycle() on the page refresh creates another child node to the existing Tree component, which already had a child. That means on page refresh Tree component gets two child nodes and there is a case in the TreeRenderer that it can have only one children, but after page refresh there are two, that is why the TreeRenderer throws the following exception. com.icesoft.faces.component.tree.MalformedTreeTagException: The tree tag requires a single child treeNode tag. Found [2] com.icesoft.faces.component.tree.TreeRenderer.encodeBegin(TreeRenderer.java:146)
        Hide
        Mircea Toma added a comment -

        It is not possible to have a Tree component that is configured to have a session bound binding and run in a cocurrentDOMView=true setup because the binding will be shared between the views. On the first request the Tree component will be created with a TreeNode as a child, on the second request the same Tree component which is acquired this time from the binding, will receive a second TreeNode instance as child.

        Really, the solution to this sort of problem would be to get rid of the child tag (ice:treeNode) since the tag doesn't add any functionality that could not be provided by the component (ice:tree) itself.

        Show
        Mircea Toma added a comment - It is not possible to have a Tree component that is configured to have a session bound binding and run in a cocurrentDOMView=true setup because the binding will be shared between the views. On the first request the Tree component will be created with a TreeNode as a child, on the second request the same Tree component which is acquired this time from the binding, will receive a second TreeNode instance as child. Really, the solution to this sort of problem would be to get rid of the child tag (ice:treeNode) since the tag doesn't add any functionality that could not be provided by the component (ice:tree) itself.
        Hide
        Luca Pertile added a comment -

        I still have the same error on Ice 1.7.2_1, also with concurrentDOMView=false. I've tried to use a request scope bean to store tree component binding, but this doesn't solve the error.
        I've partially solved the problem creating a personal renderer for Tree that remove the unwanted node from the tree in encoding method.
        This is the code in the rebderer:

        public void encodeBegin(FacesContext arg0, UIComponent arg1) throws IOException {
        // TODO Auto-generated method stub
        if (arg1 instanceof Tree) {
        Tree t = (Tree)arg1;
        if (t.getChildCount()>1)

        { t.getChildren().remove(1); }

        }
        super.encodeBegin(arg0, arg1);
        }

        it seem good fro me.

        Show
        Luca Pertile added a comment - I still have the same error on Ice 1.7.2_1, also with concurrentDOMView=false. I've tried to use a request scope bean to store tree component binding, but this doesn't solve the error. I've partially solved the problem creating a personal renderer for Tree that remove the unwanted node from the tree in encoding method. This is the code in the rebderer: public void encodeBegin(FacesContext arg0, UIComponent arg1) throws IOException { // TODO Auto-generated method stub if (arg1 instanceof Tree) { Tree t = (Tree)arg1; if (t.getChildCount()>1) { t.getChildren().remove(1); } } super.encodeBegin(arg0, arg1); } it seem good fro me.

          People

          • Assignee:
            Unassigned
            Reporter:
            Tyler Johnson
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: