ICEfaces
  1. ICEfaces
  2. ICE-6144

Initial submit causes entire form to be updated when more than one portlet is on the page.

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-Beta1
    • Fix Version/s: 2.0.0
    • Component/s: Framework
    • Labels:
      None
    • Environment:
      ICEfaces portlet portal

      Description

      The Buttons and Links portlet example in the Component Showcase behaves a bit differently under certain circumstances. Normally in Component Showcase (non-portlet version), you can do the following:

      1) Enter a value in the first input text box (e.g. foo)
      2) Click one of the submit buttons/links.
      3) The resulting update applies the new backing bean value in the bottom area.
      4) Click the Reset button to reset the form back to it's default values.

      Deployed as a portlet, the example behaves the same way as long as it is the only portlet on the page. If there are other ICEfaces portlets on the page, however, the resulting update from the initial form submission in Step 3 is much bigger than usual (the whole form). This means that the default value of the input text area is no longer "empty" but the first value that was submitted (foo). Clicking the Reset button no longer clears the input text box but resets it back to the new default value of 'foo'.

      Subsequent submissions trigger normal-sized updates (ie not the whole form) so the backing bean values are updated but not the form. This means the default value is still 'foo' and the Reset button will reset the input text to 'foo' instead of empty.

        Activity

        Hide
        Deryk Sinotte added a comment -

        I tested a sample of the Component Showcase portlets in Liferay 5. The portlets build and deploy and some work but a number of them have the same problem as outlined in the description (ie Buttons and Links in Liferay 6).

        The issue is that the first interaction with the portlet leads to a larger than expected DOM update (basically replacing the entire portlet) and this update doesn't reflect the current state on the server. As noted in the subject and description, this only seems to happen if there are 2 or more active portlets on a page. Portlets on a page by themselves appear to work fine.

        The result is that the first couple of interactions with the portlet may not work properly. Once the "big" updates are done and the state of the client is back in line with the server, the portlets start to function correctly. Apparently there's something fundamental about the first DOM-diff and update when there are multiple portlets on a page.

        The reason that more of the portlets are impacted with Liferay 5, is likely due to the fact that the bridge does not have an API in Liferay 5 for injecting resources into the head so has to use the portlet body.

        Show
        Deryk Sinotte added a comment - I tested a sample of the Component Showcase portlets in Liferay 5. The portlets build and deploy and some work but a number of them have the same problem as outlined in the description (ie Buttons and Links in Liferay 6). The issue is that the first interaction with the portlet leads to a larger than expected DOM update (basically replacing the entire portlet) and this update doesn't reflect the current state on the server. As noted in the subject and description, this only seems to happen if there are 2 or more active portlets on a page. Portlets on a page by themselves appear to work fine. The result is that the first couple of interactions with the portlet may not work properly. Once the "big" updates are done and the state of the client is back in line with the server, the portlets start to function correctly. Apparently there's something fundamental about the first DOM-diff and update when there are multiple portlets on a page. The reason that more of the portlets are impacted with Liferay 5, is likely due to the fact that the bridge does not have an API in Liferay 5 for injecting resources into the head so has to use the portlet body.
        Hide
        Deryk Sinotte added a comment -

        This problem may actually be related to ICEpush behaviour.

        I've taken the chat portlet and stripped it down to a very simple portlet where a message is simply updated when a button is clicked. There are two different buttons to click: on that initiates a Push in the actionListener method and one that doesn't. The button without Push, works fine. I can have two instances of the portlet on the same page and click them multiple times. However, when I click the button that does initiate a Push, I saw the problem occur where a ViewRoot level update is applied and the update basically replaces the whole portal page.

        Show
        Deryk Sinotte added a comment - This problem may actually be related to ICEpush behaviour. I've taken the chat portlet and stripped it down to a very simple portlet where a message is simply updated when a button is clicked. There are two different buttons to click: on that initiates a Push in the actionListener method and one that doesn't. The button without Push, works fine. I can have two instances of the portlet on the same page and click them multiple times. However, when I click the button that does initiate a Push, I saw the problem occur where a ViewRoot level update is applied and the update basically replaces the whole portal page.
        Hide
        Mircea Toma added a comment - - edited

        It seems that this issue is the result of 2 or 3 other issues combined.

        The first problem discovered is the missing ViewState input element after a form level update. Normally the ICEfaces bridge will fill in the missing element but because ICE-6022 (JSF 2.0.3 issue) the onAfterUpdate callbacks are lost, and thus not called, because the jsf.js code is evaluated a second time (when running with 2 portlets). Without ViewState parameter sent in the second submit ICEfaces will send back a ViewRoot level update since it's not able to lookup the old document to run the DOM diff.

        After patching JSF 2.0.3 (using the recommended patch in https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1814 ) the second and subsequent submits will correctly send the ViewState parameter. But, the large form level update is still received after the first submit. At a closer look it seems that the form's 'action' attribute is changed, the URL has an additional parameter (see attached DOM diff). When running with only one portlet in the page the URL is not changed thus confirming the observations described above.
        Since the URL is mangled by Portlet bridge, it was quite easy to find the culprit: http://svn.portletfaces.org/svn/portletfaces/bridge/org.portletfaces.bridge.impl/tags/2.0.0-alpha2/src/main/java/org/portletfaces/bridge/util/LiferayUtil.java
        Here's the relevant comment in the file:

        "Liferay's PortletURLImpl.toString() method sometimes adds parameters during the RENDER_PHASE which are not
        present during the RESOURCE_PHASE: p_p_col_id, p_p_col_pos, and p_p_col_count. Also, during the RESOURCE_PHASE, the toString() method will add all of the request parameter name=value pairs that were present in the XmlHttpRequest, which 1) seems unnecessary and 2) causes resourceURLs to be huge. Finally, this causes a serious inefficiency with the ICEfaces DOM-diffing engine because the HTML form element will always get DOM-diffed if actionURLs look different after a partial render than they did during the initial full render of the page. Additionally, the javax.faces.encodedURL hidden field and all other form values that have resourceURLs get DOM-diffed. The solution that this method provides is to basically make actionURLs and renderURLs look the same during the ACTION_PHASE."

        The third problem is caused by window ID handling. The window ID is generated on the server but the active portlets in the window do not share the same window ID. This causes unnecessary DOM diffs and possibly the malfunction of the window scope. In the past we discussed about this issue, one possible solution would be to let each portlet assign its own window ID and then send a list of window IDs during dispose-window request. Each portlet will then match only the window ID it knows about and dispose the corresponding scope.

        Show
        Mircea Toma added a comment - - edited It seems that this issue is the result of 2 or 3 other issues combined. The first problem discovered is the missing ViewState input element after a form level update. Normally the ICEfaces bridge will fill in the missing element but because ICE-6022 (JSF 2.0.3 issue) the onAfterUpdate callbacks are lost, and thus not called, because the jsf.js code is evaluated a second time (when running with 2 portlets). Without ViewState parameter sent in the second submit ICEfaces will send back a ViewRoot level update since it's not able to lookup the old document to run the DOM diff. After patching JSF 2.0.3 (using the recommended patch in https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1814 ) the second and subsequent submits will correctly send the ViewState parameter. But, the large form level update is still received after the first submit. At a closer look it seems that the form's 'action' attribute is changed, the URL has an additional parameter (see attached DOM diff). When running with only one portlet in the page the URL is not changed thus confirming the observations described above. Since the URL is mangled by Portlet bridge, it was quite easy to find the culprit: http://svn.portletfaces.org/svn/portletfaces/bridge/org.portletfaces.bridge.impl/tags/2.0.0-alpha2/src/main/java/org/portletfaces/bridge/util/LiferayUtil.java Here's the relevant comment in the file: "Liferay's PortletURLImpl.toString() method sometimes adds parameters during the RENDER_PHASE which are not present during the RESOURCE_PHASE: p_p_col_id, p_p_col_pos, and p_p_col_count. Also, during the RESOURCE_PHASE, the toString() method will add all of the request parameter name=value pairs that were present in the XmlHttpRequest, which 1) seems unnecessary and 2) causes resourceURLs to be huge. Finally, this causes a serious inefficiency with the ICEfaces DOM-diffing engine because the HTML form element will always get DOM-diffed if actionURLs look different after a partial render than they did during the initial full render of the page. Additionally, the javax.faces.encodedURL hidden field and all other form values that have resourceURLs get DOM-diffed. The solution that this method provides is to basically make actionURLs and renderURLs look the same during the ACTION_PHASE." The third problem is caused by window ID handling. The window ID is generated on the server but the active portlets in the window do not share the same window ID. This causes unnecessary DOM diffs and possibly the malfunction of the window scope. In the past we discussed about this issue, one possible solution would be to let each portlet assign its own window ID and then send a list of window IDs during dispose-window request. Each portlet will then match only the window ID it knows about and dispose the corresponding scope.
        Hide
        Deryk Sinotte added a comment -

        With regard to the JSF patch to the jsf.js file to prevent everything from being evaluated once, I tried to track down exactly which release contained the fix. After wading through the repositories (that are in a bit of flux due to the purchase by Oracle and the subsequent move of the Mojarra project to the new hosting system), the change has been applied as of Nov 19 and is available as part of the JSF 2.1.0_b08 release:

        ------------------------------------------------------------------------
        r8730 | sheetalv | 2010-11-23 18:00:08 -0800 (Tue, 23 Nov 2010) | 1 line

        Tag 2.1.0 Build 08
        ------------------------------------------------------------------------
        r8727 | rogerk | 2010-11-19 13:51:47 -0800 (Fri, 19 Nov 2010) | 1 line

        Mojarra Issue: 1814: Ensure jsf.js is loaded once if referenced more than once.

        The latest Glassfish that I could download as of today only seemed to included 2.1.0_b07.

        The new Mojarra project page is here: http://java.net/projects/mojarra but currently only has SVN access and no direct binary downloads that I could find. The latest promoted downloads of Glassfish can be found here: http://dlc.sun.com.edgesuite.net/glassfish/3.1/promoted/ but only went up to Nov 19th as of today.

        Show
        Deryk Sinotte added a comment - With regard to the JSF patch to the jsf.js file to prevent everything from being evaluated once, I tried to track down exactly which release contained the fix. After wading through the repositories (that are in a bit of flux due to the purchase by Oracle and the subsequent move of the Mojarra project to the new hosting system), the change has been applied as of Nov 19 and is available as part of the JSF 2.1.0_b08 release: ------------------------------------------------------------------------ r8730 | sheetalv | 2010-11-23 18:00:08 -0800 (Tue, 23 Nov 2010) | 1 line Tag 2.1.0 Build 08 ------------------------------------------------------------------------ r8727 | rogerk | 2010-11-19 13:51:47 -0800 (Fri, 19 Nov 2010) | 1 line Mojarra Issue: 1814: Ensure jsf.js is loaded once if referenced more than once. The latest Glassfish that I could download as of today only seemed to included 2.1.0_b07. The new Mojarra project page is here: http://java.net/projects/mojarra but currently only has SVN access and no direct binary downloads that I could find. The latest promoted downloads of Glassfish can be found here: http://dlc.sun.com.edgesuite.net/glassfish/3.1/promoted/ but only went up to Nov 19th as of today.
        Hide
        Deryk Sinotte added a comment -

        I did manage to find a newer "official" release of 2.0.4 9 (b_06) here:

        http://download.java.net/maven/2/com/sun/faces/

        Even though it was posted up there on the 19th (the same day that the fix for the jsf.js was made), it must have been after the .jars were posted because the fix is not in the b_06 jar.

        Show
        Deryk Sinotte added a comment - I did manage to find a newer "official" release of 2.0.4 9 (b_06) here: http://download.java.net/maven/2/com/sun/faces/ Even though it was posted up there on the 19th (the same day that the fix for the jsf.js was made), it must have been after the .jars were posted because the fix is not in the b_06 jar.
        Hide
        Deryk Sinotte added a comment -

        So for the 3 problems that Mircea identified:

        1) Mojarra jsf.js script gets evaluated multiple times - once for each portlet - causes problems with re-applying ViewState. The original case for this was http://jira.icefaces.org/browse/ICE-6022. I've re-opened/resolved it to add comments and apply changes.

        3) For better window ID handling, I've opened a new JIRA: http://jira.icefaces.org/browse/ICE-6306

        2) Changes in the form URL is leading to large updates.

        This is the specific problem that this JIRA was originally created for. For the time being, we decided that, although the behaviour is inefficient, it only appears to happen once and it does not impact or break functionality. We'll leave this case open and reduce the priority. May need to discuss with Neil regarding possible strategies in the PortletFaces bridge for handling this. The problem appears to be caused when multiple portlets are on a page and the portal adds parameters to the form action URL to include additional layout or position information. This change in the attribute of the form triggers the DOM diffing algorithm to replace the whole form. This information is only added/changed once from what we've seen in our testing so the impact is up front and results in an overly large but still successful update.

        Show
        Deryk Sinotte added a comment - So for the 3 problems that Mircea identified: 1) Mojarra jsf.js script gets evaluated multiple times - once for each portlet - causes problems with re-applying ViewState. The original case for this was http://jira.icefaces.org/browse/ICE-6022 . I've re-opened/resolved it to add comments and apply changes. 3) For better window ID handling, I've opened a new JIRA: http://jira.icefaces.org/browse/ICE-6306 2) Changes in the form URL is leading to large updates. This is the specific problem that this JIRA was originally created for. For the time being, we decided that, although the behaviour is inefficient, it only appears to happen once and it does not impact or break functionality. We'll leave this case open and reduce the priority. May need to discuss with Neil regarding possible strategies in the PortletFaces bridge for handling this. The problem appears to be caused when multiple portlets are on a page and the portal adds parameters to the form action URL to include additional layout or position information. This change in the attribute of the form triggers the DOM diffing algorithm to replace the whole form. This information is only added/changed once from what we've seen in our testing so the impact is up front and results in an overly large but still successful update.
        Hide
        Deryk Sinotte added a comment -

        Talked with Neil and, per agreement, I've created a JIRA in the PortletFaces Bridge system so that he can take a look at the behaviour.

        http://jira.portletfaces.org/browse/BRIDGE-39

        Show
        Deryk Sinotte added a comment - Talked with Neil and, per agreement, I've created a JIRA in the PortletFaces Bridge system so that he can take a look at the behaviour. http://jira.portletfaces.org/browse/BRIDGE-39
        Hide
        Neil Griffin added a comment -

        This was a bug in the bridge and was fixed here:
        http://jira.portletfaces.org/browse/BRIDGE-39

        The fix will appear in version 2.0.0-BETA3 of the bridge.

        Show
        Neil Griffin added a comment - This was a bug in the bridge and was fixed here: http://jira.portletfaces.org/browse/BRIDGE-39 The fix will appear in version 2.0.0-BETA3 of the bridge.

          People

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

            Dates

            • Created:
              Updated:
              Resolved: