ICEfaces
  1. ICEfaces
  2. ICE-3921

Exception Redirection not working correctly when JSF state-saving enabled

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Invalid
    • Affects Version/s: 1.8DR#2
    • Fix Version/s: 1.8DR#2, 1.8
    • Component/s: Framework
    • Labels:
      None
    • Environment:
      ICEfaces 1.8 DR#2 with state-saving enabled (default).
    • Workaround Exists:
      Yes
    • Workaround Description:
      Disable JSF state-saving by specifying "doJSFStateManagement=false" in the web.xml.

      Description

      Exception redirection is not working correctly when state-saving is enabled. Instead of redirecting to the specified error page, an exception is rendered in the browser.

      It looks like there's something funky going on with the request when there's an exception. We get an exception in the lifecycle, and there's an error page that's supposed to handle the case and it looks like JSF starts another lifecycle immediately to render the error page, except in this case it's finding the ViewState key in the request map still and it's trying to restore the view that it should be not.

        Activity

        Hide
        Greg Dick added a comment -

        This turns out to be caused by the exception in the test case not having a message when it is generated. When the container fetches the error resource the framework executes another lifecycle because the resource is a Faces resource (page ends in .jspx in this case). This second lifecycle is attempting to restore state because the ViewState key is still in the request map.

        This condition is noted in the JSF code and they attempt to have a workaround. The condition for a postback is

        boolean isPostBack = (isPostback(facesContext) && !isErrorPage(facesContext));

        The comment in isErrorPage is informative:

        /**

        • The Servlet specification states that if an error occurs
        • in the application and there is a matching error-page declaration,
        • the that original request the cause the error is forwarded
        • to the error page.
          *
        • If the error occurred during a post-back and a matching
        • error-page definition was found, then an attempt to restore
        • the error view would be made as the javax.faces.ViewState
        • marker would still be in the request parameters.
          *
        • Use this method to determine if the current request is
        • an error page to avoid the above condition.
          *
        • @param context the FacesContext for the current request
        • @return <code>true</code> if <code>WEBAPP_ERROR_PAGE_MARKER</code>
        • is found in the request, otherwise return <code>false</code>
          */
          private static boolean isErrorPage(FacesContext context) { return (context.getExternalContext(). getRequestMap().get(WEBAPP_ERROR_PAGE_MARKER) != null); }

        However if the exception generated is empty, the container puts nothing in the WEBAPP_ERROR_PAGE_MARKER request parameter for the request for the subsequent resource.

        This would fail in stock JSF also. Only ICEfaces without state saving would work in this case, because with an existing viewRoot, the application wouldn't attempt to restore any viewRoot at all.

        Show
        Greg Dick added a comment - This turns out to be caused by the exception in the test case not having a message when it is generated. When the container fetches the error resource the framework executes another lifecycle because the resource is a Faces resource (page ends in .jspx in this case). This second lifecycle is attempting to restore state because the ViewState key is still in the request map. This condition is noted in the JSF code and they attempt to have a workaround. The condition for a postback is boolean isPostBack = (isPostback(facesContext) && !isErrorPage(facesContext)); The comment in isErrorPage is informative: /** The Servlet specification states that if an error occurs in the application and there is a matching error-page declaration, the that original request the cause the error is forwarded to the error page. * If the error occurred during a post-back and a matching error-page definition was found, then an attempt to restore the error view would be made as the javax.faces.ViewState marker would still be in the request parameters. * Use this method to determine if the current request is an error page to avoid the above condition. * @param context the FacesContext for the current request @return <code>true</code> if <code>WEBAPP_ERROR_PAGE_MARKER</code> is found in the request, otherwise return <code>false</code> */ private static boolean isErrorPage(FacesContext context) { return (context.getExternalContext(). getRequestMap().get(WEBAPP_ERROR_PAGE_MARKER) != null); } However if the exception generated is empty, the container puts nothing in the WEBAPP_ERROR_PAGE_MARKER request parameter for the request for the subsequent resource. This would fail in stock JSF also. Only ICEfaces without state saving would work in this case, because with an existing viewRoot, the application wouldn't attempt to restore any viewRoot at all.

          People

          • Assignee:
            Unassigned
            Reporter:
            Ken Fyten
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: