javaserverfaces
  1. javaserverfaces
  2. JAVASERVERFACES-2053

Tree creation is broken when using <cc:insertChildren> directly in <cc:implementation>

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Trivial Trivial
    • Resolution: Incomplete
    • Affects Version/s: 2.0.3, 2.0.4, 2.1.0, 2.1.1
    • Fix Version/s: None
    • Labels:
      None

      Description

      While analyzing the state issue JAVASERVERFACES-2040 I found out that the tree creation is broken on postback when using <cc:insertChildren> directly in <cc:implementation>.

      The relevant composite components will look like this:
      <cc:implementation>
      <cc:insertChildren />
      </cc:implementation>

      What will happen on postback:
      1.) The view will be created fine in restoreView phase. This includes the invocation of com.sun.faces.facelets.tag.composite.InsertChildrenHandler.RelocateChildrenListener that will move the childs of the composite component (UINamingContainer) to the implicit panel of the composite component implementation.

      2.) In renderView phase the facelets tree is applied a second time. But this time com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.ComponentTagHandlerDelegateImpl will not find the already existing childs of the composite component because they were relocated. The relevant method com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.findReparentedComponent() will never be called in this case.
      As a result new child components will be created (with invalid state).

      If insertChildren is nested inside a component the relocating code will work as expected. The working components will look like this:
      <cc:implementation>
      <someRealUIComponent>
      <cc:insertChildren />
      </someRealUIComponent>
      </cc:implementation>

        Issue Links

          Activity

          Hide
          Mathias Werlitz added a comment -

          I created a patch for JAVASERVERFACES-2040 that will also fix this sub issue.

          Show
          Mathias Werlitz added a comment - I created a patch for JAVASERVERFACES-2040 that will also fix this sub issue.
          Hide
          Mathias Werlitz added a comment -

          I attached an updated version of the small test application illustrating the resulting wrong state of the composite component (and inserted components) of this ticket an JAVASERVERFACES-2040.

          This application contains 4 pages which use one of the 4 very similar composite components.
          index.xhtml -> composite component with direct insert children
          index2.xhtml -> composite component with non-direct insert children (workaround for some parts of this issue)
          indexFacet.xhtml -> composite component with a facet to render children (workaround for some parts of this issue)
          indexNoChild.xhtml -> composite component with no "inserted childs"

          Two phase listerners modify the state of the composite component and do some assertions.
          In order to invoke the test you have to open a page and click the command button.

          In all 4 cases the state of the composite component or the inserted childs is more or less corruped.
          For example in "indexNoChild.xhtml" an 500 error "java.lang.IllegalStateException: Composite component state does not match the state after INVOKE_APPLICATION." should appear.

          All the assertions (one is specific for Mojarra) are passed with the latest MyFaces impl.

          Show
          Mathias Werlitz added a comment - I attached an updated version of the small test application illustrating the resulting wrong state of the composite component (and inserted components) of this ticket an JAVASERVERFACES-2040 . This application contains 4 pages which use one of the 4 very similar composite components. index.xhtml -> composite component with direct insert children index2.xhtml -> composite component with non-direct insert children (workaround for some parts of this issue) indexFacet.xhtml -> composite component with a facet to render children (workaround for some parts of this issue) indexNoChild.xhtml -> composite component with no "inserted childs" Two phase listerners modify the state of the composite component and do some assertions. In order to invoke the test you have to open a page and click the command button. In all 4 cases the state of the composite component or the inserted childs is more or less corruped. For example in "indexNoChild.xhtml" an 500 error "java.lang.IllegalStateException: Composite component state does not match the state after INVOKE_APPLICATION." should appear. All the assertions (one is specific for Mojarra) are passed with the latest MyFaces impl.
          Hide
          Manfred Riem added a comment -

          Can you verify if this is still an issue on the latest 2.1 release?

          Show
          Manfred Riem added a comment - Can you verify if this is still an issue on the latest 2.1 release?
          Hide
          Manfred Riem added a comment -

          Lowering priority because of no response

          Show
          Manfred Riem added a comment - Lowering priority because of no response
          Hide
          Manfred Riem added a comment -

          Lowering priority because of no response (of anyone)

          Show
          Manfred Riem added a comment - Lowering priority because of no response (of anyone)
          Hide
          Manfred Riem added a comment -

          Closing because of inactivity

          Show
          Manfred Riem added a comment - Closing because of inactivity
          Hide
          Mathias Werlitz added a comment -

          Sorry, I could not respond here for a long time.

          I have tested the most recent versions 2.1.25 and 2.2.2:
          Most of the problems reported in this issue and JAVASERVERFACES-2040 seem to be fixed in the recent versions. However there are still two things that are still not correct from my point of view.

          1. In the RENDER_RESPONSE phase a composite component instance has 2 instances of com.sun.faces.facelets.tag.composite.InsertChildrenHandler$RelocateChildrenListener attached to it. This is the case if <cc:insertChildren /> is used and this seems to be wrong. One instance should be enough and shows there is still something wrong.

          2. The state of the composite component itself still gets lost (because of applying meta data twice). An attribute of the composite component that is modified in the INVOKE_APPLICATION phase will be reset to the initial (template) value after a postback and has the wrong value in the following RENDER_RESPONSE phase.

          Please reopen the issue.

          Show
          Mathias Werlitz added a comment - Sorry, I could not respond here for a long time. I have tested the most recent versions 2.1.25 and 2.2.2: Most of the problems reported in this issue and JAVASERVERFACES-2040 seem to be fixed in the recent versions. However there are still two things that are still not correct from my point of view. 1. In the RENDER_RESPONSE phase a composite component instance has 2 instances of com.sun.faces.facelets.tag.composite.InsertChildrenHandler$RelocateChildrenListener attached to it. This is the case if <cc:insertChildren /> is used and this seems to be wrong. One instance should be enough and shows there is still something wrong. 2. The state of the composite component itself still gets lost (because of applying meta data twice). An attribute of the composite component that is modified in the INVOKE_APPLICATION phase will be reset to the initial (template) value after a postback and has the wrong value in the following RENDER_RESPONSE phase. Please reopen the issue.
          Hide
          Frank Caputo added a comment - - edited

          I also observed this behavior with 2.1.28 and 2.1.29. The children are rendered right before the actual composite component. As a workaround I surrounded <composite:insertChildren /> with <ui:fragment>.

          Show
          Frank Caputo added a comment - - edited I also observed this behavior with 2.1.28 and 2.1.29. The children are rendered right before the actual composite component. As a workaround I surrounded <composite:insertChildren /> with <ui:fragment>.
          Hide
          Manfred Riem added a comment -

          Closing this out again. Note if an issue is closed out because of inactivity we do not reopen it. A new issue needs to be created.

          Show
          Manfred Riem added a comment - Closing this out again. Note if an issue is closed out because of inactivity we do not reopen it. A new issue needs to be created.
          Hide
          Frank Caputo added a comment -

          I didn't know that, who should file the new issue?

          Show
          Frank Caputo added a comment - I didn't know that, who should file the new issue?
          Hide
          Manfred Riem added a comment -

          Hi Frank, preferably the person that says they are experiencing the problem as well. And then send a reproducer to issues@javaserverfaces.java.net. No worries, we instituted this change a while back so we don't have issues reopened from years or months ago.

          Show
          Manfred Riem added a comment - Hi Frank, preferably the person that says they are experiencing the problem as well. And then send a reproducer to issues@javaserverfaces.java.net. No worries, we instituted this change a while back so we don't have issues reopened from years or months ago.

            People

            • Assignee:
              Unassigned
              Reporter:
              Mathias Werlitz
            • Votes:
              9 Vote for this issue
              Watchers:
              9 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: