ICEfaces
  1. ICEfaces
  2. ICE-2990

Seam exception redirecting not working with ICEFaces

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.7Beta1
    • Fix Version/s: 1.7.2
    • Component/s: None
    • Labels:
      None
    • Environment:
      JBoss 4.2.2.GA, JDK6

      Description

      setting debug mode to false (facelets debug to false in web.xml, seam core debug false, removing seam debug jar)
      adding to home.xhtml a

      <ice:form>
      <ice:commandButton value="NPE" action="#{npe.npe}"/>
      </ice:form>

      and a

      @Name("npe")
      public class NPE {
      public void npe() {
      throw new NullPointerException("npe");
      }
      }

      clicking the NPE hangs the application instead of redirecting according to the catch-all pages.xml exception handler

      debug mode shows redirect to errors.xhtml and block/errors.xhtml but results in hang.

        Issue Links

          Activity

          Hide
          Nicklas Karlsson added a comment -

          seam-generated, libs removed

          Show
          Nicklas Karlsson added a comment - seam-generated, libs removed
          Hide
          Ken Fyten added a comment -

          Need to verify that the fix for ICE-3007 resolves this issue as well.

          Show
          Ken Fyten added a comment - Need to verify that the fix for ICE-3007 resolves this issue as well.
          Hide
          Judy Guglielmin added a comment -

          It seems that any exceptions (SQLException, NPE, etc), that the methods throw are not being caught at this time (1.7.0 and 1.7.1). Also tried without Seam (using Facelets and ICEfaces-1.7.1) and the redirection is not occuring (when placing the following in web.xml:-

          <error-page>
          <exception-type>java.lang.Exception</exception-type>
          <location>/error.seam</location>
          </error-page>

          (also tried with various exceptions from methods tied to actionListeners on ice:commandLinks--> stack trace is dumped to AS console, but redirection not occurring).

          Show
          Judy Guglielmin added a comment - It seems that any exceptions (SQLException, NPE, etc), that the methods throw are not being caught at this time (1.7.0 and 1.7.1). Also tried without Seam (using Facelets and ICEfaces-1.7.1) and the redirection is not occuring (when placing the following in web.xml:- <error-page> <exception-type>java.lang.Exception</exception-type> <location>/error.seam</location> </error-page> (also tried with various exceptions from methods tied to actionListeners on ice:commandLinks--> stack trace is dumped to AS console, but redirection not occurring).
          Hide
          Mandeep Hayher added a comment -

          The fix for ICE-3332 does not resolve the problem with seam application. Seam exception redirecting still not working.

          Show
          Mandeep Hayher added a comment - The fix for ICE-3332 does not resolve the problem with seam application. Seam exception redirecting still not working.
          Hide
          Ken Fyten added a comment -

          Judy says:

          I have created 3 separate applications to trace through this, 1=Seam only, 2=ICEfaces facelets only, 3=Seam plus ICefaces.

          What is happening is the following:-

          1) Seam catches the exception and wraps it in it's own Exception Class. ExceptionFilter then does it's thing and ends the conversation nicely, created a MockFacesContext and creates a new temporary conversation, then uses FacesManager/Manager to do redirect() and redirection is based on rules in pages.xml.
          2) ICEfaces:- exception caught in ViewBoundServer and thrown to be caught in MainServlet. Regular jsf stuff will do redirect based on what is in web.xml for this.
          3) ICEfaces with Seam. The ViewBoundServer finds the exception and throws it, then the view is released (contexts and state, etc released), BUT....the ExceptionFilter then tries to do it's thing....but no contexts there no conversation to restore. It ends up creating MockFacesContext with a new temporary conversation and tries to do the redirect, but it just hangs (forever). Doesn't come back to MainServlet.

          This reflects the same issue as when a user has incorrect permissions on various methods.....since this is caught the same way in seam, we don't do the proper redirect. Just an exception and the hanging.

          Show
          Ken Fyten added a comment - Judy says: I have created 3 separate applications to trace through this, 1=Seam only, 2=ICEfaces facelets only, 3=Seam plus ICefaces. What is happening is the following:- 1) Seam catches the exception and wraps it in it's own Exception Class. ExceptionFilter then does it's thing and ends the conversation nicely, created a MockFacesContext and creates a new temporary conversation, then uses FacesManager/Manager to do redirect() and redirection is based on rules in pages.xml. 2) ICEfaces:- exception caught in ViewBoundServer and thrown to be caught in MainServlet. Regular jsf stuff will do redirect based on what is in web.xml for this. 3) ICEfaces with Seam. The ViewBoundServer finds the exception and throws it, then the view is released (contexts and state, etc released), BUT....the ExceptionFilter then tries to do it's thing....but no contexts there no conversation to restore. It ends up creating MockFacesContext with a new temporary conversation and tries to do the redirect, but it just hangs (forever). Doesn't come back to MainServlet. This reflects the same issue as when a user has incorrect permissions on various methods.....since this is caught the same way in seam, we don't do the proper redirect. Just an exception and the hanging.
          Hide
          Jack Van Ooststroom added a comment -

          After some extensive research and trying different potential fixes I came to the following conclusion:

          I think the offending Seam class is org.jboss.seam.mock.MockViewHandler, which is created when the org.jboss.seam.web.ExceptionFilter catches an exception. It contains the getActionURL(FacesContext, String) which seems to be used to determine the URI to redirect to:

          @Override
          public String getActionURL(FacesContext ctx, String viewId)
          {
          String contextPath = ctx.getExternalContext().getRequestContextPath();
          String pathInfo = ctx.getExternalContext().getRequestPathInfo();
          String servletPath = ctx.getExternalContext().getRequestServletPath();

          if (Strings.isEmpty(pathInfo))

          { int loc = viewId.lastIndexOf('.'); if (loc<0) throw new IllegalArgumentException("no file extension in view id: " + viewId); int sploc = servletPath.lastIndexOf('.'); if (sploc<0) throw new IllegalArgumentException("no file extension in servlet path: " + servletPath); return contextPath + viewId.substring(0, loc) + servletPath.substring(sploc); }

          else

          { return contextPath + servletPath + viewId; }

          }

          In combination with ICEfaces when the NPE is forcibly thrown the Strings in this part of the code contain the following values (with some comments in the brackets after the values):

          • viewId: /error.xhtml (the desired error page defined in pages.xml)
          • contextPath: /ICE (the ICEfaces application name)
          • pathInfo: /send-receive-updates (ICEfaces JavaScript Bridge specific)
          • servletPath: /block (ICEfaces JavaScript Bridge specific)

          This will result in a redirect URI of /ICE/block/error.xhtml (and some query part, which I will ignore for the moment) which is incorrect in my opinion. The else-block in the method doesn't take the details of viewId into account. As the desired error page is specified as /error.xhtml the resulting redirect URI should toss the servletPath as the viewId starts with a slash. (On a side note, if a full URI is specified in the pages.xml, all the elements (contextPath, pathInfo and servletPath should be ignored and the viewId itself should be the redirect URI.)

          Additionally, the "xhtml" part of the resulting redirect URI doesn't seem to be replaced by "seam". I'm not sure in this case if we do something wrong that causes this.

          By the way, I used JBoss Seam 2.0.2.SP1 for all of this.

          Ted contacted somebody at Seam to verify my suspicion.

          Show
          Jack Van Ooststroom added a comment - After some extensive research and trying different potential fixes I came to the following conclusion: I think the offending Seam class is org.jboss.seam.mock.MockViewHandler, which is created when the org.jboss.seam.web.ExceptionFilter catches an exception. It contains the getActionURL(FacesContext, String) which seems to be used to determine the URI to redirect to: @Override public String getActionURL(FacesContext ctx, String viewId) { String contextPath = ctx.getExternalContext().getRequestContextPath(); String pathInfo = ctx.getExternalContext().getRequestPathInfo(); String servletPath = ctx.getExternalContext().getRequestServletPath(); if (Strings.isEmpty(pathInfo)) { int loc = viewId.lastIndexOf('.'); if (loc<0) throw new IllegalArgumentException("no file extension in view id: " + viewId); int sploc = servletPath.lastIndexOf('.'); if (sploc<0) throw new IllegalArgumentException("no file extension in servlet path: " + servletPath); return contextPath + viewId.substring(0, loc) + servletPath.substring(sploc); } else { return contextPath + servletPath + viewId; } } In combination with ICEfaces when the NPE is forcibly thrown the Strings in this part of the code contain the following values (with some comments in the brackets after the values): viewId: /error.xhtml (the desired error page defined in pages.xml) contextPath: /ICE (the ICEfaces application name) pathInfo: /send-receive-updates (ICEfaces JavaScript Bridge specific) servletPath: /block (ICEfaces JavaScript Bridge specific) This will result in a redirect URI of /ICE/block/error.xhtml (and some query part, which I will ignore for the moment) which is incorrect in my opinion. The else-block in the method doesn't take the details of viewId into account. As the desired error page is specified as /error.xhtml the resulting redirect URI should toss the servletPath as the viewId starts with a slash. (On a side note, if a full URI is specified in the pages.xml, all the elements (contextPath, pathInfo and servletPath should be ignored and the viewId itself should be the redirect URI.) Additionally, the "xhtml" part of the resulting redirect URI doesn't seem to be replaced by "seam". I'm not sure in this case if we do something wrong that causes this. By the way, I used JBoss Seam 2.0.2.SP1 for all of this. Ted contacted somebody at Seam to verify my suspicion.
          Hide
          Judy Guglielmin added a comment -
          Show
          Judy Guglielmin added a comment - created JBSEAM-3426 https://jira.jboss.org/jira/browse/JBSEAM-3426
          Hide
          Judy Guglielmin added a comment -

          after Pete's fix for JBSEAM-3426, this will work if you put .seam extension to redirects for exception handling with seam (eg: <redirect view-id="/error.seam">). BUT we can do better than this if we don't have ctx.getExternalContext().getRequestPathInfo() return as null. Looking at ServletExternalContext, the getRequestServletPath evaluates to what requestPathInfo should be, so could set RequestPathInfo to requestServletPath if exception caught and is Seam application (in com.icesoft.faces.webapp.http.coreReceiveSendUpdates).

          Show
          Judy Guglielmin added a comment - after Pete's fix for JBSEAM-3426, this will work if you put .seam extension to redirects for exception handling with seam (eg: <redirect view-id="/error.seam">). BUT we can do better than this if we don't have ctx.getExternalContext().getRequestPathInfo() return as null. Looking at ServletExternalContext, the getRequestServletPath evaluates to what requestPathInfo should be, so could set RequestPathInfo to requestServletPath if exception caught and is Seam application (in com.icesoft.faces.webapp.http.coreReceiveSendUpdates).
          Hide
          Judy Guglielmin added a comment -

          changes made to PortletExternalContext and ServletExternalContext to ensure that the request variables are maintained in the externalContext for Seam redirection.

          Show
          Judy Guglielmin added a comment - changes made to PortletExternalContext and ServletExternalContext to ensure that the request variables are maintained in the externalContext for Seam redirection.
          Hide
          Judy Guglielmin added a comment -

          tested on jboss-4.2.3.GA as well. Requires Seam trunk (for Pete's fix) and ICEfaces fix will be in 1.7.2 release

          Show
          Judy Guglielmin added a comment - tested on jboss-4.2.3.GA as well. Requires Seam trunk (for Pete's fix) and ICEfaces fix will be in 1.7.2 release
          Hide
          Ken Fyten added a comment -

          This change is causing regressions in server-push with Seam:

          08:28:18,568 ERROR [STDERR] Exception in thread "Render Thread - 22"
          08:28:18,568 ERROR [STDERR] java.lang.StackOverflowError
          08:28:18,568 ERROR [STDERR] at org.apache.catalina.connector.Request.setAttribute(Request.java:1424)
          08:28:18,568 ERROR [STDERR] at org.apache.catalina.connector.RequestFacade.setAttribute(RequestFacade.java:503)
          08:28:18,568 ERROR [STDERR] at javax.servlet.ServletRequestWrapper.setAttribute(ServletRequestWrapper.java:284)
          08:28:18,568 ERROR [STDERR] at com.icesoft.faces.webapp.http.servlet.ServletRequestAttributes.setAttribute(ServletRequestAttributes.java:28)
          08:28:18,568 ERROR [STDERR] at com.icesoft.faces.webapp.http.servlet.ServletEnvironmentRequest.setAttribute(ServletEnvironmentRequest.java:216)
          08:28:18,568 ERROR [STDERR] at com.icesoft.faces.webapp.http.servlet.ServletRequestAttributeMap.setAttribute(ServletRequestAttributeMap.java:25)
          08:28:18,568 ERROR [STDERR] at com.icesoft.faces.context.AbstractCopyingAttributeMap.put(AbstractCopyingAttributeMap.java:22)
          08:28:18,568 ERROR [STDERR] at java.util.Collections$SynchronizedMap.put(Unknown Source)
          08:28:18,568 ERROR [STDERR] at org.jboss.seam.contexts.BasicContext.set(BasicContext.java:85)
          08:28:18,568 ERROR [STDERR] at org.jboss.seam.Component.newInstance(Component.java:2031)

          Show
          Ken Fyten added a comment - This change is causing regressions in server-push with Seam: 08:28:18,568 ERROR [STDERR] Exception in thread "Render Thread - 22" 08:28:18,568 ERROR [STDERR] java.lang.StackOverflowError 08:28:18,568 ERROR [STDERR] at org.apache.catalina.connector.Request.setAttribute(Request.java:1424) 08:28:18,568 ERROR [STDERR] at org.apache.catalina.connector.RequestFacade.setAttribute(RequestFacade.java:503) 08:28:18,568 ERROR [STDERR] at javax.servlet.ServletRequestWrapper.setAttribute(ServletRequestWrapper.java:284) 08:28:18,568 ERROR [STDERR] at com.icesoft.faces.webapp.http.servlet.ServletRequestAttributes.setAttribute(ServletRequestAttributes.java:28) 08:28:18,568 ERROR [STDERR] at com.icesoft.faces.webapp.http.servlet.ServletEnvironmentRequest.setAttribute(ServletEnvironmentRequest.java:216) 08:28:18,568 ERROR [STDERR] at com.icesoft.faces.webapp.http.servlet.ServletRequestAttributeMap.setAttribute(ServletRequestAttributeMap.java:25) 08:28:18,568 ERROR [STDERR] at com.icesoft.faces.context.AbstractCopyingAttributeMap.put(AbstractCopyingAttributeMap.java:22) 08:28:18,568 ERROR [STDERR] at java.util.Collections$SynchronizedMap.put(Unknown Source) 08:28:18,568 ERROR [STDERR] at org.jboss.seam.contexts.BasicContext.set(BasicContext.java:85) 08:28:18,568 ERROR [STDERR] at org.jboss.seam.Component.newInstance(Component.java:2031)
          Hide
          Ken Fyten added a comment -

          Seems like the push issues are not related to this issue. New JIRA for those is ICE-3577.

          Marking Fixed again.

          Show
          Ken Fyten added a comment - Seems like the push issues are not related to this issue. New JIRA for those is ICE-3577 . Marking Fixed again.
          Hide
          Judy Guglielmin added a comment -

          for pre jboss-seam-2.1.0.GA releases, you can still do redirection with ICEfaces and Seam by configuring the following:_

          1) in web.xml add the following, and ensure error.xhtml (or whatever extension is defined in context-param = javax.faces.DEFAULT_SUFFIX) is included in the project:-
          <error-page>
          <exception-type>java.lang.Exception</exception-type>
          <location>/error.seam</location>
          </error-page>

          Note that multiple exceptions may be listed going to numerous error pages that are defined.

          2) Add the following to components.xml:-

          <web:exception-filter url-pattern="*.seam"/>

          and define the namespace for web:- xmlns:web="http://jboss.com/products/seam/web" with schema location= http://jboss.com/products/seam/web http://jboss.com/products/seam/web-2.0.xsd

          (for 2.0.x)

          That's it. You can't get the actual value of the exception, but if you defined an error page for each type of exception you wanted to capture as well as a general catch-all, you could have static pages to inform the user what had happened.

          Show
          Judy Guglielmin added a comment - for pre jboss-seam-2.1.0.GA releases, you can still do redirection with ICEfaces and Seam by configuring the following:_ 1) in web.xml add the following, and ensure error.xhtml (or whatever extension is defined in context-param = javax.faces.DEFAULT_SUFFIX) is included in the project:- <error-page> <exception-type>java.lang.Exception</exception-type> <location>/error.seam</location> </error-page> Note that multiple exceptions may be listed going to numerous error pages that are defined. 2) Add the following to components.xml:- <web:exception-filter url-pattern="*.seam"/> and define the namespace for web:- xmlns:web="http://jboss.com/products/seam/web" with schema location= http://jboss.com/products/seam/web http://jboss.com/products/seam/web-2.0.xsd (for 2.0.x) That's it. You can't get the actual value of the exception, but if you defined an error page for each type of exception you wanted to capture as well as a general catch-all, you could have static pages to inform the user what had happened.
          Hide
          Judy Guglielmin added a comment -

          Just to make things clear(er?):-

          what has been explained above is a "workaround" for versions of Seam previous to jboss-seam-2.1.0. The fix has been applied to both jboss-seam-2.1.0 as well as ICEfaces-1.7.2 to enable the seam redirection navigation (dependent on rules defined in pages.xml) to work.

          Show
          Judy Guglielmin added a comment - Just to make things clear(er?):- what has been explained above is a "workaround" for versions of Seam previous to jboss-seam-2.1.0. The fix has been applied to both jboss-seam-2.1.0 as well as ICEfaces-1.7.2 to enable the seam redirection navigation (dependent on rules defined in pages.xml) to work.

            People

            • Assignee:
              Unassigned
              Reporter:
              Nicklas Karlsson
            • Votes:
              10 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: