ICEfaces
  1. ICEfaces
  2. ICE-7097

MyFaces state saving has different timing which impacts some components

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0.2
    • Fix Version/s: 2.1-Beta2, 3.0
    • Component/s: Framework, ICE-Components
    • Labels:
      None
    • Environment:
      ICEfaces 2 MyFaces 2

      Description

      In trying to get MyFaces running with ICEfaces 2 (ICE-5868) I found that a couple of components are not operating properly due to the timing of state saving. The two currently known components with issues are:

      OutputChart: after the chart is initially rendered, clicking on the image map points generates an NPE
      Caused by: java.lang.NullPointerException
      at com.icesoft.faces.component.outputchart.OutputChart.getGeneratedImageMapArea(OutputChart.java:414)
      at com.icesoft.faces.component.outputchart.OutputChart.decode(OutputChart.java:359)
      at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1204)
      at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1198)
      at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1198)
      at javax.faces.component.UIForm.processDecodes(UIForm.java:114)
      at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1198)
      at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1198)
      at javax.faces.component.UIViewRoot._processDecodesDefault(UIViewRoot.java:1320)
      ...

      Progress Bar: the progress bar is not updated even though Push is operating properly.

        Issue Links

          Activity

          Deryk Sinotte created issue -
          Hide
          Deryk Sinotte added a comment -

          Both of the component issues are related to the strategy and timing of state saving in MyFaces.

          With Mojarra, a marker/placeholder is used and state saving is not done until getViewState() is actually called. In Mojarra, this is done when the response is being written and the marker is being replaced.

          With MyFaces, a marker is not used and getViewState() is called during the normal render process to inject the ViewState into the page. However, state saving is also done at this time but only once (as an optimization). Because of this, elements on the page that have not finished setting various state related values will not have those values saved and restored properly. For example, note the order of events as they are logged when the progress bar is updating:

          OutputProgress.saveState: null
          OutputProgressModel.setPercentComplete: 50
          OutputProgress.restoreState: null
          OutputProgressModel.getPercentComplete: 0
          OutputProgressRenderer.setPercentage: 0

          The issue is similar for the Chart component as the actual Chart resource is not state saved and is therefore not available to be restored when the user clicks on the image map.

          Show
          Deryk Sinotte added a comment - Both of the component issues are related to the strategy and timing of state saving in MyFaces. With Mojarra, a marker/placeholder is used and state saving is not done until getViewState() is actually called. In Mojarra, this is done when the response is being written and the marker is being replaced. With MyFaces, a marker is not used and getViewState() is called during the normal render process to inject the ViewState into the page. However, state saving is also done at this time but only once (as an optimization). Because of this, elements on the page that have not finished setting various state related values will not have those values saved and restored properly. For example, note the order of events as they are logged when the progress bar is updating: OutputProgress.saveState: null OutputProgressModel.setPercentComplete: 50 OutputProgress.restoreState: null OutputProgressModel.getPercentComplete: 0 OutputProgressRenderer.setPercentage: 0 The issue is similar for the Chart component as the actual Chart resource is not state saved and is therefore not available to be restored when the user clicks on the image map.
          Deryk Sinotte made changes -
          Field Original Value New Value
          Salesforce Case []
          Assignee Deryk Sinotte [ deryk.sinotte ]
          Hide
          Deryk Sinotte added a comment -

          Linking to the parent JIRA for overall MyFaces 2 compatibility

          Show
          Deryk Sinotte added a comment - Linking to the parent JIRA for overall MyFaces 2 compatibility
          Deryk Sinotte made changes -
          Link This issue blocks ICE-5868 [ ICE-5868 ]
          Deryk Sinotte made changes -
          Link This issue is duplicated by ICE-5967 [ ICE-5967 ]
          Repository Revision Date User Message
          ICEsoft Public SVN Repository #25326 Wed Aug 24 15:05:06 MDT 2011 deryk.sinotte ICE-7097: mimic the Mojarra mark-and-replace ViewState strategy for MyFaces in compat forms
          Files Changed
          Commit graph MODIFY /icefaces2/trunk/icefaces/compat/core/src/main/java/com/icesoft/faces/context/CompatDOMPartialViewContext.java
          Commit graph MODIFY /icefaces2/trunk/icefaces/core/src/main/java/org/icefaces/impl/context/DOMResponseWriter.java
          Commit graph MODIFY /icefaces2/trunk/icefaces/compat/core/src/main/java/com/icesoft/faces/renderkit/dom_html_basic/FormRenderer.java
          Commit graph MODIFY /icefaces2/trunk/icefaces/core/src/main/java/org/icefaces/util/EnvUtils.java
          Hide
          Deryk Sinotte added a comment -

          While trying to correct the ViewState issue in compat forms on the client-side does provide some success, I don't think it's a good long term solution. Some information to illustrate the point:

          Mojarra and MyFaces handle state saving in different ways. Mojarra has a mechanism for installing a ViewState marker and then replacing that during the initial page render so that the state is actually only saved at the end of the lifecycle. State saving is done for each getViewState() call. This "mark and replace" approach is different than MyFaces which doesn't use a marker.

          In ICEfaces, there are currently 2 types of Form renderers, standard h:form (handled by the JSF implementation, either Mojarra or MyFaces) and ice:form (which is handled by our own custom renderer). We have special Mojarra processing in this custom renderer so that the ViewState is included. We need to also ensure that the ViewState is also included when running with MyFaces.

          Full page renders in Mojarra (which includes the ViewState) are different than partial page updates (which do not include the ViewState). ICEfaces DOM processing relies on certain behaviour here where the ViewState is written during the full page write but afterward removed from the DOM so that it is not there during a DOM diff. Without this logic, updates would always be full form updates. Again, something we need to cater to with MyFaces as well.

          Also to consider are the number of forms per view and the number of views per page (e.g. portlets). The use cases are a combination of these two variables:

          single view, single form
          This is probably the most typical use case of a normal web app.

          single view, multiple forms
          This is also a fairly common use case.

          multiple views, single form
          While multiple views is a typical portlet scenario, I wouldn't expect only one portlet on the page to have a single form. There would likely be one or more forms per view.

          multiple views, multiple forms
          This is the typical portlet use case.

          Without some fairly complex tracking, it would be more difficult to handle the portlet use cases on the client side. Instead, since each view should know it's own state, handling the ViewState processing on the server-side makes more sense.

          Show
          Deryk Sinotte added a comment - While trying to correct the ViewState issue in compat forms on the client-side does provide some success, I don't think it's a good long term solution. Some information to illustrate the point: Mojarra and MyFaces handle state saving in different ways. Mojarra has a mechanism for installing a ViewState marker and then replacing that during the initial page render so that the state is actually only saved at the end of the lifecycle. State saving is done for each getViewState() call. This "mark and replace" approach is different than MyFaces which doesn't use a marker. In ICEfaces, there are currently 2 types of Form renderers, standard h:form (handled by the JSF implementation, either Mojarra or MyFaces) and ice:form (which is handled by our own custom renderer). We have special Mojarra processing in this custom renderer so that the ViewState is included. We need to also ensure that the ViewState is also included when running with MyFaces. Full page renders in Mojarra (which includes the ViewState) are different than partial page updates (which do not include the ViewState). ICEfaces DOM processing relies on certain behaviour here where the ViewState is written during the full page write but afterward removed from the DOM so that it is not there during a DOM diff. Without this logic, updates would always be full form updates. Again, something we need to cater to with MyFaces as well. Also to consider are the number of forms per view and the number of views per page (e.g. portlets). The use cases are a combination of these two variables: single view, single form This is probably the most typical use case of a normal web app. single view, multiple forms This is also a fairly common use case. multiple views, single form While multiple views is a typical portlet scenario, I wouldn't expect only one portlet on the page to have a single form. There would likely be one or more forms per view. multiple views, multiple forms This is the typical portlet use case. Without some fairly complex tracking, it would be more difficult to handle the portlet use cases on the client side. Instead, since each view should know it's own state, handling the ViewState processing on the server-side makes more sense.
          Hide
          Deryk Sinotte added a comment -

          Resolving as fixed. Code was checked in to make MyFaces behave much the same as it does with Mojarra when using compat components. Our custom FormRenderer sticks in a placeholder and then the DOMResponseWriter replaces the placeholder at the appropriate time while removing the actual node from the DOM (to avoid unnecessary DOM diff related updates).

          Show
          Deryk Sinotte added a comment - Resolving as fixed. Code was checked in to make MyFaces behave much the same as it does with Mojarra when using compat components. Our custom FormRenderer sticks in a placeholder and then the DOMResponseWriter replaces the placeholder at the appropriate time while removing the actual node from the DOM (to avoid unnecessary DOM diff related updates).
          Deryk Sinotte made changes -
          Status Open [ 1 ] Resolved [ 5 ]
          Resolution Fixed [ 1 ]
          Ken Fyten made changes -
          Fix Version/s 2.1-Beta2 [ 10294 ]
          Ken Fyten made changes -
          Status Resolved [ 5 ] Closed [ 6 ]

            People

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

              Dates

              • Created:
                Updated:
                Resolved: