ICEfaces
  1. ICEfaces
  2. ICE-7014

<ice:inputText> within composite components lose value if validation fails

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: EE-2.0.0.GA
    • Fix Version/s: 3.0, EE-2.0.0.GA_P01
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      Tomcat 7.0.14, Mojarra 2.1.2
    • Assignee Priority:
      P1
    • Affects:
      Compatibility/Configuration

      Description

      Given this example with prop:fieldset and prop:properyText being Composite Components and an ice:inputText within propertyText:

      <prop:fieldset>
      <prop:propertyText value="#{myBean.myValue}">
      <f:validateLength for="input" minimum="5"/>
      </prop:propertyText>
      </prop:fieldset>

      If validation fails, the ice:inputText within prop:propertyText loses its value if validation fails. This doesn't happen with an h:inputText.

       It also does NOT happen, if prop:fieldset is removed. So the bug actually only happens if the parent of composite component containing the ice:inputText is a composite component too.

        Activity

        Hide
        Adrian Gygax added a comment -

        Attached example Eclipse project.

        To reproduce the bug just enter something with less than 5 chars to trigger validation failure.

        Remove the surrounding prop:fieldset in index.xhtml to verify the bug doesn't happen then
        Replace ice:inputText with h:inputText in propertyText.xhtml to verify it works with h:inputText

        BTW: We are using ice:inputText because we need to set an action on the inputText. We also assume that this problem happens also with other compatibily components where there is no easy replacement (e. g. selectInputDate).

        Show
        Adrian Gygax added a comment - Attached example Eclipse project. To reproduce the bug just enter something with less than 5 chars to trigger validation failure. Remove the surrounding prop:fieldset in index.xhtml to verify the bug doesn't happen then Replace ice:inputText with h:inputText in propertyText.xhtml to verify it works with h:inputText BTW: We are using ice:inputText because we need to set an action on the inputText. We also assume that this problem happens also with other compatibily components where there is no easy replacement (e. g. selectInputDate).
        Hide
        Tyler Johnson added a comment -

        Attaching war file intended for deployment on Tomcat.

        Show
        Tyler Johnson added a comment - Attaching war file intended for deployment on Tomcat.
        Hide
        Mark Collette added a comment -

        When testing, I noted that if the value is first empty, or is first a valid full long string, and then you change the inputted text to having greater than zero length, but being too short, then the new short submittedValue is lost, and the ice:inputText reverts to the previous value. This does not happen with h:inputText.

        I investigated what was happening to the submittedValue, to see who was clearing it. In short, the submittedValue is not getting cleared out, but rather a different component instance is being used for rendering than for decoding. And no state saving is occurring in-between execution and rendering, to propagate the submittedValue to the new component.

        Show
        Mark Collette added a comment - When testing, I noted that if the value is first empty, or is first a valid full long string, and then you change the inputted text to having greater than zero length, but being too short, then the new short submittedValue is lost, and the ice:inputText reverts to the previous value. This does not happen with h:inputText. I investigated what was happening to the submittedValue, to see who was clearing it. In short, the submittedValue is not getting cleared out, but rather a different component instance is being used for rendering than for decoding. And no state saving is occurring in-between execution and rendering, to propagate the submittedValue to the new component.
        Hide
        Ted Goddard added a comment -

        Perhaps the components within the composite component are being recreated by facelets for the two different phases. Is h:inputText a new instance as well?

        Show
        Ted Goddard added a comment - Perhaps the components within the composite component are being recreated by facelets for the two different phases. Is h:inputText a new instance as well?
        Hide
        Mark Collette added a comment -

        Added a phase listener that prints out the component tree both before and after each phase. Found that when validation fails, between after-validation and before-render, the inner of the two composite components and everything within it is a new component reference. The rest of the component tree, including the outer composite component, are all the same old component references. Because of it being a new ice:inputText, with no state saving happening, the submittedValue is lost.

        Show
        Mark Collette added a comment - Added a phase listener that prints out the component tree both before and after each phase. Found that when validation fails, between after-validation and before-render, the inner of the two composite components and everything within it is a new component reference. The rest of the component tree, including the outer composite component, are all the same old component references. Because of it being a new ice:inputText, with no state saving happening, the submittedValue is lost.
        Hide
        Mark Collette added a comment -

        Using apache-tomcat-6.0.29 and:

        • My modified version of sc10273 example app with my trunk icefaces jars, and h:inputText
        • My modified version of sc10273 example app with my the original ee icefaces jars, and h:inputText
        • The original war saved on my hard drive, but h:inputText
        • The original war re-downloaded from the jira, but h:inputText

        I could not reproduce the behaviour being different, and working, with h:inputText. Instead, I observed h:inputText having the same problem as ice:inputText.

        Show
        Mark Collette added a comment - Using apache-tomcat-6.0.29 and: My modified version of sc10273 example app with my trunk icefaces jars, and h:inputText My modified version of sc10273 example app with my the original ee icefaces jars, and h:inputText The original war saved on my hard drive, but h:inputText The original war re-downloaded from the jira, but h:inputText I could not reproduce the behaviour being different, and working, with h:inputText. Instead, I observed h:inputText having the same problem as ice:inputText.
        Hide
        Adrian Gygax added a comment -

        Hey Mark, I just re-verified the bug with unmodified versions of the redownloaded Eclipse project as well as the war. I'm still having the behaviour as reported. Maybe we're not testing the same so I will describe a bit more what I am doing (Tomcat 6.0.32, Java 1.6.0_18):

        1. Start Tomcat with app deployed
        2. http://localhost:8080/ice/index.xhtml
        3. Enter "asdf" into the text field
        4. Click on "Submit"

        Here is what I observe using h:inputText/ice:inputText in "resources\prop\propertyText.xhtml"

        ice:inputText:

        • Text field is cleared
        • Validation message appears

        Ajax response (Note that it includes an update for the textfield with an empty value):
        <partial-response>
        <changes>
        <update id="myForm:j_idt6:j_idt7:input"><input class="iceInpTxt textInput" id="myForm:j_idt6:j_idt7:input" name="myForm:j_idt6:j_idt7:input" onblur="setFocus('');" onfocus="setFocus(this.id);" onkeypress="iceSubmit(form,this,event);" onmousedown="this.focus();" style="" type="text" value="" /></update>
        <update id="myForm:j_idt6:j_idt7:message"><span class="iceMsgError" id="myForm:j_idt6:j_idt7:message"> : &#220;berpr&#252;fungsfehler: L&#228;nge ist kleiner als der zul&#228;ssige Minimalwert &#34;5&#34; </span></update>
        <update id="dynamic-code-compat"><span id="dynamic-code-compat"></span></update>
        <update id="javax.faces.ViewState">-6866908854304177373:-5524502648703393485</update>
        <eval>ice.applyFocus('myForm:submitButton');</eval>
        </changes>
        </partial-response>


        h:inputText:

        • Text field still contains "asdf"
        • Validation message appears

        Ajax response (Note that it DOES NOT include an update for the textfield):
        <partial-response>
        <changes>
        <update id="myForm:j_idt6:j_idt7:message"><span class="iceMsgError" id="myForm:j_idt6:j_idt7:message"> : &#220;berpr&#252;fungsfehler: L&#228;nge ist kleiner als der zul&#228;ssige Minimalwert &#34;5&#34; </span></update>
        <update id="dynamic-code-compat"><span id="dynamic-code-compat"></span></update>
        <update id="javax.faces.ViewState">-7498020932363666203:-8383812554977269016</update>
        <eval>ice.applyFocus('myForm:submitButton');</eval>
        </changes>
        </partial-response>

        Show
        Adrian Gygax added a comment - Hey Mark, I just re-verified the bug with unmodified versions of the redownloaded Eclipse project as well as the war. I'm still having the behaviour as reported. Maybe we're not testing the same so I will describe a bit more what I am doing (Tomcat 6.0.32, Java 1.6.0_18): 1. Start Tomcat with app deployed 2. http://localhost:8080/ice/index.xhtml 3. Enter "asdf" into the text field 4. Click on "Submit" Here is what I observe using h:inputText/ice:inputText in "resources\prop\propertyText.xhtml" — ice:inputText: Text field is cleared Validation message appears Ajax response (Note that it includes an update for the textfield with an empty value): <partial-response> <changes> <update id="myForm:j_idt6:j_idt7:input"><input class="iceInpTxt textInput" id="myForm:j_idt6:j_idt7:input" name="myForm:j_idt6:j_idt7:input" onblur="setFocus('');" onfocus="setFocus(this.id);" onkeypress="iceSubmit(form,this,event);" onmousedown="this.focus();" style="" type="text" value="" /></update> <update id="myForm:j_idt6:j_idt7:message"><span class="iceMsgError" id="myForm:j_idt6:j_idt7:message"> : &#220;berpr&#252;fungsfehler: L&#228;nge ist kleiner als der zul&#228;ssige Minimalwert &#34;5&#34; </span></update> <update id="dynamic-code-compat"><span id="dynamic-code-compat"></span></update> <update id="javax.faces.ViewState">-6866908854304177373:-5524502648703393485</update> <eval>ice.applyFocus('myForm:submitButton');</eval> </changes> </partial-response> — h:inputText: Text field still contains "asdf" Validation message appears Ajax response (Note that it DOES NOT include an update for the textfield): <partial-response> <changes> <update id="myForm:j_idt6:j_idt7:message"><span class="iceMsgError" id="myForm:j_idt6:j_idt7:message"> : &#220;berpr&#252;fungsfehler: L&#228;nge ist kleiner als der zul&#228;ssige Minimalwert &#34;5&#34; </span></update> <update id="dynamic-code-compat"><span id="dynamic-code-compat"></span></update> <update id="javax.faces.ViewState">-7498020932363666203:-8383812554977269016</update> <eval>ice.applyFocus('myForm:submitButton');</eval> </changes> </partial-response>
        Hide
        Mark Collette added a comment -

        With the three code examples I had previously been using and not http:/localhost:8080/sc10273/ and first entering valid input of greater than 5 characters and then invalid input of les than 5 characters. I now tried with http:/localhost:8080/sc10273/index.xhtml and immediately entering invalid characters. It still did not show h:inputText retaining the value.

        Next I will try newer versions of apache and different browsers. I've been using Chrome 13.

        Show
        Mark Collette added a comment - With the three code examples I had previously been using and not http:/localhost:8080/sc10273/ and first entering valid input of greater than 5 characters and then invalid input of les than 5 characters. I now tried with http:/localhost:8080/sc10273/index.xhtml and immediately entering invalid characters. It still did not show h:inputText retaining the value. Next I will try newer versions of apache and different browsers. I've been using Chrome 13.
        Hide
        Adrian Gygax added a comment -

        I can confirm your observations that h:inputText and ice:inputText behave the same. I think the problem was that I didn't close the browser in-between my tests.

        Because what I just discovered now is that without ever having entered a valid entry only the first invalid entry is lost. The second invalid entry is retained with both ice:inputText and h:inputText (IE 8 and Firefox 3.6.17).

        Show
        Adrian Gygax added a comment - I can confirm your observations that h:inputText and ice:inputText behave the same. I think the problem was that I didn't close the browser in-between my tests. Because what I just discovered now is that without ever having entered a valid entry only the first invalid entry is lost. The second invalid entry is retained with both ice:inputText and h:inputText (IE 8 and Firefox 3.6.17).
        Hide
        Mark Collette added a comment -

        Using Safari and quitting and restarting between tests, I found that h:inputText loses the invalid input the first submit, but then retains invalid input on subsequent submits of the same session.

        Show
        Mark Collette added a comment - Using Safari and quitting and restarting between tests, I found that h:inputText loses the invalid input the first submit, but then retains invalid input on subsequent submits of the same session.
        Hide
        Mark Collette added a comment -

        Again, using Safari, and quitting and restarting between tests, after having changed all my versions of the test to use ice:inputText, I found that it lost the invalid input on the first submit as well as subsequent ones. So this does differ from h:inputText for me, in the subsequent submits.

        Show
        Mark Collette added a comment - Again, using Safari, and quitting and restarting between tests, after having changed all my versions of the test to use ice:inputText, I found that it lost the invalid input on the first submit as well as subsequent ones. So this does differ from h:inputText for me, in the subsequent submits.
        Hide
        Ted Goddard added a comment -

        I have confirmed Mark's observation that the inputText within two composite components is being instantiated twice: once in RESTORE_VIEW and once in RENDER_RESPONSE. I am now investigating the root cause of this.

        Show
        Ted Goddard added a comment - I have confirmed Mark's observation that the inputText within two composite components is being instantiated twice: once in RESTORE_VIEW and once in RENDER_RESPONSE. I am now investigating the root cause of this.
        Hide
        Ted Goddard added a comment -

        Problem occurs with both full and partial state saving.

        <context-param>
        <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
        <param-value>false</param-value>
        </context-param>

        It appears that inputText state is being saved, but is just not being used correctly during RENDER_RESPONSE. This is likely a JSF bug, but it will be necessary to understand the root cause to file a proper bug report.

        Show
        Ted Goddard added a comment - Problem occurs with both full and partial state saving. <context-param> <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name> <param-value>false</param-value> </context-param> It appears that inputText state is being saved, but is just not being used correctly during RENDER_RESPONSE. This is likely a JSF bug, but it will be necessary to understand the root cause to file a proper bug report.
        Hide
        Ted Goddard added a comment -

        More careful testing with partial state saving disabled shows that the value is retained on the second submission (it is lost on the first submit as with partial state saving enabled).

        Show
        Ted Goddard added a comment - More careful testing with partial state saving disabled shows that the value is retained on the second submission (it is lost on the first submit as with partial state saving enabled).
        Hide
        Ted Goddard added a comment -

        In com.sun.faces.facelets.tag.jsf.ComponentSupport.findChildByTagId() we have:

        cid = (String) c.getAttributes().get(MARK_CREATED);

        if (id.equals(cid))

        { return c; }

        Dumping out the children for the case where the cid is null

        if (null == cid) {
        Iterator everything = c.getFacetsAndChildren();
        while (everything.hasNext())

        { c = (UIComponent) everything.next(); System.out.println("child of null " + c); }

        }

        shows

        <fieldset>
        <legend>
        child of null javax.faces.component.html.HtmlOutputText@27a5dac0
        child of null </legend>
        <ol>

        child of null javax.faces.component.UINamingContainer@50af8fc0
        child of null
        </ol>
        </fieldset>

        which is the outer composite component. It's not clear if the tagid is permitted to be null. To understand this would require further analysis of Facelet view restoration.

        The recommended approach is to file a mojarra bug with a simplified test case (not containing ICEfaces) mentioning that the tagid is null for this case. It is very possible that the null tagid is legitimate and the composite component parent is not being found for other reasons.

        Show
        Ted Goddard added a comment - In com.sun.faces.facelets.tag.jsf.ComponentSupport.findChildByTagId() we have: cid = (String) c.getAttributes().get(MARK_CREATED); if (id.equals(cid)) { return c; } Dumping out the children for the case where the cid is null if (null == cid) { Iterator everything = c.getFacetsAndChildren(); while (everything.hasNext()) { c = (UIComponent) everything.next(); System.out.println("child of null " + c); } } shows <fieldset> <legend> child of null javax.faces.component.html.HtmlOutputText@27a5dac0 child of null </legend> <ol> child of null javax.faces.component.UINamingContainer@50af8fc0 child of null </ol> </fieldset> which is the outer composite component. It's not clear if the tagid is permitted to be null. To understand this would require further analysis of Facelet view restoration. The recommended approach is to file a mojarra bug with a simplified test case (not containing ICEfaces) mentioning that the tagid is null for this case. It is very possible that the null tagid is legitimate and the composite component parent is not being found for other reasons.
        Hide
        Ted Goddard added a comment -

        We can assist with mojarra bug reporting and potentially generate a mojarra patch, but at the moment will close this as "Won't fix" due to the fact that it is not an ICEfaces bug.

        Show
        Ted Goddard added a comment - We can assist with mojarra bug reporting and potentially generate a mojarra patch, but at the moment will close this as "Won't fix" due to the fact that it is not an ICEfaces bug.
        Hide
        Ted Goddard added a comment -

        Attached mangled "noice" exploded .war file. This contains modified mojarra classes used for debugging. To test with MyFaces, all classes/javax and classes/com should be removed.

        Show
        Ted Goddard added a comment - Attached mangled "noice" exploded .war file. This contains modified mojarra classes used for debugging. To test with MyFaces, all classes/javax and classes/com should be removed.
        Hide
        Ted Goddard added a comment -

        Please test the noice version with MyFaces.

        Show
        Ted Goddard added a comment - Please test the noice version with MyFaces.
        Hide
        Ted Goddard added a comment -

        Reopening for MyFaces testing.

        Show
        Ted Goddard added a comment - Reopening for MyFaces testing.
        Hide
        Mark Collette added a comment -

        For completeness, I looked into h:inputText, to see what's happening with the component tree, and found that the inner composite component and everything within it is a new component reference, between AFTER validation and BEFORE render, as well.

        Show
        Mark Collette added a comment - For completeness, I looked into h:inputText, to see what's happening with the component tree, and found that the inner composite component and everything within it is a new component reference, between AFTER validation and BEFORE render, as well.
        Hide
        Deryk Sinotte added a comment -
        Show
        Deryk Sinotte added a comment - Opened up http://java.net/jira/browse/JAVASERVERFACES-2164 for this issue.
        Hide
        Deryk Sinotte added a comment - - edited

        I should also note that I've tested this with a recent version of MyFaces and it does not exhibit the problem. However, it possible that MyFaces may not be handling the dynamic includes correctly and is dodging the issue.

        Show
        Deryk Sinotte added a comment - - edited I should also note that I've tested this with a recent version of MyFaces and it does not exhibit the problem. However, it possible that MyFaces may not be handling the dynamic includes correctly and is dodging the issue.
        Hide
        Deryk Sinotte added a comment -

        Turns out the issue had already been reported as per (which includes a workaround):

        http://java.net/jira/browse/JAVASERVERFACES-1991

        Looks like there a number of related issues that hinge on this as well. Another developer has provided a patch in:

        http://java.net/jira/browse/JAVASERVERFACES-2040

        which indicates what looks to be a more fundamental problem with composite components in Mojarra but it has not been fixed/applied yet.

        Show
        Deryk Sinotte added a comment - Turns out the issue had already been reported as per (which includes a workaround): http://java.net/jira/browse/JAVASERVERFACES-1991 Looks like there a number of related issues that hinge on this as well. Another developer has provided a patch in: http://java.net/jira/browse/JAVASERVERFACES-2040 which indicates what looks to be a more fundamental problem with composite components in Mojarra but it has not been fixed/applied yet.
        Hide
        Adrian Gygax added a comment -

        After applying the workaround from JAVASERVERFACES-1991 I still have this problem.

        However, the workaround fixes the problem, that a textfield's content is always reset to the last valid value if you change it's content to an invalid value.

        Show
        Adrian Gygax added a comment - After applying the workaround from JAVASERVERFACES-1991 I still have this problem. However, the workaround fixes the problem, that a textfield's content is always reset to the last valid value if you change it's content to an invalid value.
        Hide
        Ken Fyten added a comment -

        This is believed to be an issue for Mojarra to resolve.

        Show
        Ken Fyten added a comment - This is believed to be an issue for Mojarra to resolve.

          People

          • Assignee:
            Deryk Sinotte
            Reporter:
            Adrian Gygax
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: