ICEfaces
  1. ICEfaces
  2. ICE-4791

Convert ExternalContext methods to use wrapped request directly rather than request attributes

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.8.1
    • Fix Version/s: 1.8.2-RC1, 1.8.2
    • Component/s: None
    • Labels:
      None
    • Environment:
      Icefaces 1.8.1 from trank with jsf library updated to 1.2_13

      Description

      After update from 1.2_12 to 1.2_13 error "block.jspx Not Found in
      ExternalContext as a Resource" started appears.

      I don't know is the problem in jsf or icefaces layer?

      Full user case in https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1231

        Activity

        Hide
        Krashan Brahmanjara added a comment -

        User case
        If i try to read not existing bundle properties then error is catched and
        rediected to error page. It works under 1.2_12 but not under 1.2_13 - custom
        errorpage is not displayed

        Stack trace under 1.2_12
        SEVERE: Servlet.service() for servlet Blocking Servlet threw exception
        javax.el.PropertyNotFoundException: /bar.jspx @48,141
        onclick="window.open('#

        {msgHelp[test:concat(edit.helpLink)]}

        ','_help');return
        false;": Property 'usermode-1' not found on type java.util.PropertyResourceBundle
        at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:73)
        at
        javax.faces.component.html.HtmlCommandButton.getOnclick(HtmlCommandButton.java:335)

        Stack trace under 1.2_13

        SEVERE: Servlet.service() for servlet Blocking Servlet threw exception
        javax.el.PropertyNotFoundException: /bar.jspx @48,141
        onclick="window.open('#

        {msgHelp[test:concat(edit.helpLink)]}

        ','_help');return
        false;": Property 'usermode-1' not found on type java.util.PropertyResourceBundle
        at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:73)
        at
        javax.faces.component.html.HtmlCommandButton.getOnclick(HtmlCommandButton.java:335)

        2009-08-03 12:10:52 org.apache.catalina.core.ApplicationDispatcher invoke
        SEVERE: Servlet.service() for servlet Persistent Faces Servlet threw exception
        java.io.FileNotFoundException: /block.jspx Not Found in ExternalContext as a
        Resource
        at
        com.sun.facelets.impl.DefaultFaceletFactory.resolveURL(DefaultFaceletFactory.java:121)
        at
        com.sun.facelets.impl.DefaultFaceletFactory.getFacelet(DefaultFaceletFactory.java:91)
        at
        com.icesoft.faces.facelets.D2DFaceletViewHandler.renderResponse(D2DFaceletViewHandler.java:268)
        at com.icesoft.faces.application.D2DViewHandler.renderView(D2DViewHandler.java:153)
        at
        com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
        at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
        at
        com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor.apply(JsfLifecycleExecutor.java:19)
        at com.icesoft.faces.context.View$2$1.respond(View.java:48)
        at
        com.icesoft.faces.webapp.http.servlet.ServletRequestResponse.respondWith(ServletRequestResponse.java:201)
        at com.icesoft.faces.context.View$2.serve(View.java:77)
        at com.icesoft.faces.context.View.servePage(View.java:149)
        at
        com.icesoft.faces.webapp.http.core.SingleViewServer.service(SingleViewServer.java:52)
        at com.icesoft.faces.webapp.http.common.ServerProxy.service(ServerProxy.java:11)
        at
        com.icesoft.faces.webapp.http.servlet.MainSessionBoundServlet$4.service(MainSessionBoundServlet.java:133)
        at
        com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:24)
        at
        com.icesoft.faces.webapp.http.servlet.BasicAdaptingServlet.service(BasicAdaptingServlet.java:16)
        at
        com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
        at
        com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:47)
        at
        com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
        at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:135)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

        2009-08-03 12:10:52 org.apache.catalina.core.StandardHostValve custom
        SEVERE: Exception Processing ErrorPage[exceptionType=java.lang.Throwable,
        location=/error.iface]
        javax.servlet.ServletException: java.lang.Exception: javax.faces.FacesException:
        Problem in renderResponse: /block.jspx Not Found in ExternalContext as a Resource
        at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:162)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

        Caused by: java.lang.Exception: javax.faces.FacesException: Problem in
        renderResponse: /block.jspx Not Found in ExternalContext as a Resource
        at com.icesoft.faces.context.View.servePage(View.java:152)
        at
        com.icesoft.faces.webapp.http.core.SingleViewServer.service(SingleViewServer.java:52)

        Caused by: javax.faces.FacesException: Problem in renderResponse: /block.jspx
        Not Found in ExternalContext as a Resource
        at
        com.icesoft.faces.facelets.D2DFaceletViewHandler.renderResponse(D2DFaceletViewHandler.java:296)
        at com.icesoft.faces.application.D2DViewHandler.renderView(D2DViewHandler.java:153)
        at
        com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)

        Caused by: java.io.FileNotFoundException: /block.jspx Not Found in
        ExternalContext as a Resource
        at
        com.sun.facelets.impl.DefaultFaceletFactory.resolveURL(DefaultFaceletFactory.java:121)
        at
        com.sun.facelets.impl.DefaultFaceletFactory.getFacelet(DefaultFaceletFactory.java:91)

        Show
        Krashan Brahmanjara added a comment - User case If i try to read not existing bundle properties then error is catched and rediected to error page. It works under 1.2_12 but not under 1.2_13 - custom errorpage is not displayed Stack trace under 1.2_12 SEVERE: Servlet.service() for servlet Blocking Servlet threw exception javax.el.PropertyNotFoundException: /bar.jspx @48,141 onclick="window.open('# {msgHelp[test:concat(edit.helpLink)]} ','_help');return false;": Property 'usermode-1' not found on type java.util.PropertyResourceBundle at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:73) at javax.faces.component.html.HtmlCommandButton.getOnclick(HtmlCommandButton.java:335) Stack trace under 1.2_13 SEVERE: Servlet.service() for servlet Blocking Servlet threw exception javax.el.PropertyNotFoundException: /bar.jspx @48,141 onclick="window.open('# {msgHelp[test:concat(edit.helpLink)]} ','_help');return false;": Property 'usermode-1' not found on type java.util.PropertyResourceBundle at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:73) at javax.faces.component.html.HtmlCommandButton.getOnclick(HtmlCommandButton.java:335) 2009-08-03 12:10:52 org.apache.catalina.core.ApplicationDispatcher invoke SEVERE: Servlet.service() for servlet Persistent Faces Servlet threw exception java.io.FileNotFoundException: /block.jspx Not Found in ExternalContext as a Resource at com.sun.facelets.impl.DefaultFaceletFactory.resolveURL(DefaultFaceletFactory.java:121) at com.sun.facelets.impl.DefaultFaceletFactory.getFacelet(DefaultFaceletFactory.java:91) at com.icesoft.faces.facelets.D2DFaceletViewHandler.renderResponse(D2DFaceletViewHandler.java:268) at com.icesoft.faces.application.D2DViewHandler.renderView(D2DViewHandler.java:153) at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100) at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) at com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor.apply(JsfLifecycleExecutor.java:19) at com.icesoft.faces.context.View$2$1.respond(View.java:48) at com.icesoft.faces.webapp.http.servlet.ServletRequestResponse.respondWith(ServletRequestResponse.java:201) at com.icesoft.faces.context.View$2.serve(View.java:77) at com.icesoft.faces.context.View.servePage(View.java:149) at com.icesoft.faces.webapp.http.core.SingleViewServer.service(SingleViewServer.java:52) at com.icesoft.faces.webapp.http.common.ServerProxy.service(ServerProxy.java:11) at com.icesoft.faces.webapp.http.servlet.MainSessionBoundServlet$4.service(MainSessionBoundServlet.java:133) at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:24) at com.icesoft.faces.webapp.http.servlet.BasicAdaptingServlet.service(BasicAdaptingServlet.java:16) at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23) at com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:47) at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23) at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:135) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 2009-08-03 12:10:52 org.apache.catalina.core.StandardHostValve custom SEVERE: Exception Processing ErrorPage[exceptionType=java.lang.Throwable, location=/error.iface] javax.servlet.ServletException: java.lang.Exception: javax.faces.FacesException: Problem in renderResponse: /block.jspx Not Found in ExternalContext as a Resource at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:162) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) Caused by: java.lang.Exception: javax.faces.FacesException: Problem in renderResponse: /block.jspx Not Found in ExternalContext as a Resource at com.icesoft.faces.context.View.servePage(View.java:152) at com.icesoft.faces.webapp.http.core.SingleViewServer.service(SingleViewServer.java:52) Caused by: javax.faces.FacesException: Problem in renderResponse: /block.jspx Not Found in ExternalContext as a Resource at com.icesoft.faces.facelets.D2DFaceletViewHandler.renderResponse(D2DFaceletViewHandler.java:296) at com.icesoft.faces.application.D2DViewHandler.renderView(D2DViewHandler.java:153) at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110) Caused by: java.io.FileNotFoundException: /block.jspx Not Found in ExternalContext as a Resource at com.sun.facelets.impl.DefaultFaceletFactory.resolveURL(DefaultFaceletFactory.java:121) at com.sun.facelets.impl.DefaultFaceletFactory.getFacelet(DefaultFaceletFactory.java:91)
        Hide
        Krashan Brahmanjara added a comment -

        I created empty block.jspx. Now I can see empty page without block.jspx stacktrace.

        Quick workaround - go back to jsf.1.2_12.

        Show
        Krashan Brahmanjara added a comment - I created empty block.jspx. Now I can see empty page without block.jspx stacktrace. Quick workaround - go back to jsf.1.2_12.
        Hide
        Ryan Lubke added a comment -

        I've found the reason for the change in behavior between 1.2_12 and 1.2_13.

        In 1.2_12, we would attempt to derive the view ID by casting the request to HttpServletRequest like so:

        if (viewId == null) {
        Object request = facesContext.getExternalContext().getRequest();
        if (request instanceof HttpServletRequest)

        { viewId = ((HttpServletRequest) request).getServletPath(); }

        }

        In an effort to remove as many Servlet dependencies as possible, we changed the method call
        to call through to ExternalContext.getRequestServletPath()

        if (viewId == null)

        { viewId = facesContext.getExternalContext().getRequestServletPath(); }

        ICEFaces' implementation of this method does:

        ServletExternalContext:
        -----------------------------------------------------
        public String getRequestServletPath() {
        //crazy "workaround": solves the different behaviour MyFaces and Icefaces (including Sun-RI) need from this method
        boolean callFromMyfaces = new Exception().getStackTrace()[1].getClassName().startsWith("org.apache.myfaces");
        if (callFromMyfaces)

        { return requestServletPath == null ? initialRequest.getServletPath() : requestServletPath; }

        else

        { String servletPath = (String) initialRequest.getAttribute("javax.servlet.forward.servlet_path"); return servletPath == null ? initialRequest.getServletPath() : servletPath; }

        }

        In the error page case, the call:

        initialRequest.getAttribute("javax.servlet.forward.servlet_path");

        returns /block. This causes the viewID to eventually be block.jsp or block.xhtml (as above).

        Show
        Ryan Lubke added a comment - I've found the reason for the change in behavior between 1.2_12 and 1.2_13. In 1.2_12, we would attempt to derive the view ID by casting the request to HttpServletRequest like so: if (viewId == null) { Object request = facesContext.getExternalContext().getRequest(); if (request instanceof HttpServletRequest) { viewId = ((HttpServletRequest) request).getServletPath(); } } In an effort to remove as many Servlet dependencies as possible, we changed the method call to call through to ExternalContext.getRequestServletPath() if (viewId == null) { viewId = facesContext.getExternalContext().getRequestServletPath(); } ICEFaces' implementation of this method does: ServletExternalContext: ----------------------------------------------------- public String getRequestServletPath() { //crazy "workaround": solves the different behaviour MyFaces and Icefaces (including Sun-RI) need from this method boolean callFromMyfaces = new Exception().getStackTrace() [1] .getClassName().startsWith("org.apache.myfaces"); if (callFromMyfaces) { return requestServletPath == null ? initialRequest.getServletPath() : requestServletPath; } else { String servletPath = (String) initialRequest.getAttribute("javax.servlet.forward.servlet_path"); return servletPath == null ? initialRequest.getServletPath() : servletPath; } } In the error page case, the call: initialRequest.getAttribute("javax.servlet.forward.servlet_path"); returns /block. This causes the viewID to eventually be block.jsp or block.xhtml (as above).
        Hide
        Deryk Sinotte added a comment -

        Assigning to Mircea:

        Please review to see if we can simply the MyFaces runtime check as well as the forwarding logic (is it still necessary given that we don't forward from BlockingServlet any longer but we do still from MainPortlet).

        Show
        Deryk Sinotte added a comment - Assigning to Mircea: Please review to see if we can simply the MyFaces runtime check as well as the forwarding logic (is it still necessary given that we don't forward from BlockingServlet any longer but we do still from MainPortlet).
        Hide
        Mircea Toma added a comment - - edited

        Well, I looked though ServletExternalContext history but I could not find the reason why "javax.servlet.forward.servlet_path" attribute was used. Its usage was introduced in revision 14562 for issues ICE-1910, ICE-1826, and ICE-1886. By analyzing the usage paths of ServletExternalContext.getRequestServletPath I discovered that neither the core code nor JSF-RI's running code is using this method. Since 14562 revision contained a patch for D2DViewHandler.getResourceURL method I conclude that only the changes to D2DViewHandler actually fixed the listed issues (... actually the issue descriptions confirm this conclusion).
        The fix changed ServletExternalContext.getRequestServletPath method to not use the "javax.servlet.forward.servlet_path" attribute at all.

        Show
        Mircea Toma added a comment - - edited Well, I looked though ServletExternalContext history but I could not find the reason why "javax.servlet.forward.servlet_path" attribute was used. Its usage was introduced in revision 14562 for issues ICE-1910 , ICE-1826 , and ICE-1886 . By analyzing the usage paths of ServletExternalContext.getRequestServletPath I discovered that neither the core code nor JSF-RI's running code is using this method. Since 14562 revision contained a patch for D2DViewHandler.getResourceURL method I conclude that only the changes to D2DViewHandler actually fixed the listed issues (... actually the issue descriptions confirm this conclusion). The fix changed ServletExternalContext.getRequestServletPath method to not use the "javax.servlet.forward.servlet_path" attribute at all.
        Hide
        Mircea Toma added a comment - - edited

        Stopped reading "javax.servlet.forward.context_path" attribute since web-application's context cannot change during a forward.
        Also removed BridgeExternalContext.getRequestURI method and its implementations since the method is used by dead code in D2DViewHandler. Removed unused methods in D2DViewHandler as well.

        Show
        Mircea Toma added a comment - - edited Stopped reading "javax.servlet.forward.context_path" attribute since web-application's context cannot change during a forward. Also removed BridgeExternalContext.getRequestURI method and its implementations since the method is used by dead code in D2DViewHandler. Removed unused methods in D2DViewHandler as well.

          People

          • Assignee:
            Mircea Toma
            Reporter:
            Krashan Brahmanjara
          • Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: