[JBoss JIRA] Created: (RF-4411) ViewExpiredException when transferred to error page declared in web.xml
by Fabien Gaujous (JIRA)
ViewExpiredException when transferred to error page declared in web.xml
-----------------------------------------------------------------------
Key: RF-4411
URL: https://jira.jboss.org/jira/browse/RF-4411
Project: RichFaces
Issue Type: Bug
Affects Versions: 3.1.4
Environment: RichFaces 3.1.4 GA, MyFaces 1.2.2, Facelets 1.1.14, Tomcat 6
Reporter: Fabien Gaujous
Hello,
When a backing bean throws an Exception (HibernateException in our case), instead of being redirected to the error page declared in web.xml, we end up with the default Tomcat 500 error page.
This is due to a a ViewExpiredException that is triggered while the system attempts to perform the Restore View JSF phase for the page with view id "/500.xhtml".
Here is the stack trace from the Tomcat log:
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:613)
Sep 5, 2008 4:58:00 PM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet HWFacesServlet threw exception
javax.faces.application.ViewExpiredException: /500.xhtmlThe expected view was not returned for the view identifier: /500.xhtml
at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:88)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:103)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:148)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:630)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:438)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:424)
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:343)
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:287)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:613)
Sep 5, 2008 4:58:00 PM org.apache.catalina.core.StandardHostValve custom
SEVERE: Exception Processing ErrorPage[errorCode=500, location=/faces/500.xhtml]
javax.servlet.ServletException: /500.xhtmlThe expected view was not returned for the view identifier: /500.xhtml
at javax.faces.webapp._ErrorPageWriter.throwException(_ErrorPageWriter.java:401)
at javax.faces.webapp.FacesServlet.handleLifecycleException(FacesServlet.java:221)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:156)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:630)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:438)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:424)
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:343)
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:287)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:613)
Caused by: javax.faces.application.ViewExpiredException: /500.xhtmlThe expected view was not returned for the view identifier: /500.xhtml
at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:88)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:103)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:148)
... 17 more
Our web.xml is as follows:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>App</display-name>
<context-param>
<param-name>facelets.VIEW_MAPPINGS</param-name>
<param-value>*.xhtml</param-value>
</context-param>
<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/tags/kpu/kpu.taglib.xml</param-value>
</context-param>
<context-param>
<param-name>facelets.DEVELOPMENT</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>facelets.REFRESH_PERIOD</param-name>
<param-value>-1</param-value>
</context-param>
<context-param>
<param-name>facelets.SKIP_COMMENTS</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<description>http://wiki.apache.org/myfaces/RedirectTracker</description>
<param-name>org.apache.myfaces.redirectTracker.POLICY</param-name>
<param-value>org.apache.myfaces.custom.redirectTracker.policy.FullRedirectTrackPolicy</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.RENDER_VIEWSTATE_ID</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.ERROR_HANDLING</param-name>
<param-value>false</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<filter>
<description>This filter is the Ajax4JSF</description>
<display-name>Ajax4jsf Filter</display-name>
<filter-name>ajax4jsf</filter-name>
<filter-class>org.ajax4jsf.Filter</filter-class>
</filter>
<filter>
<description>This is the MyFaces extension</description>
<filter-name>extensionsFilter</filter-name>
<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
<init-param>
<param-name>uploadMaxFileSize</param-name>
<param-value>500k</param-value>
</init-param>
<init-param>
<param-name>uploadThresholdSize</param-name>
<param-value>1k</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>extensionsFilter</filter-name>
<url-pattern>/faces/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>extensionsFilter</filter-name>
<servlet-name>HWFacesServlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>ajax4jsf</filter-name>
<servlet-name>HWFacesServlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>HWFacesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HWFacesServlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<!-- Error page handling -->
<error-page>
<error-code>500</error-code>
<location>/faces/500.xhtml</location>
</error-page>
</web-app>
Here is what we found from our investigation.
When submitting a login form from page "/login.xhtml", our code triggers a HibernateException. This generates a 500 error.
Then, in org.apache.myfaces.lifecycle.RestoreViewExecutor#execute, when reaching the Restore View JSF phase for view id "/500.xhtml", restoreViewSupport.isPostback(facesContext) is true, and thus, thinking this is a postback situation (which is weird as we are moving to a different page, the error one), the system attempts to restore a viewroot using the current view state.
The problem is, there is no existing view state in the session for view id "/500.xhtml" -- there is only state for the page we are coming from and which triggered the HibernateException, "/login.xhtml" (the view state is searched / computed in org.ajax4jsf.application.AjaxStateManager#restoreView). So the viewRoot returned by viewHandler.restoreView(facesContext, viewId) is null, and a ViewExpiredException is thrown. The default Tomcat error page is then shown.
// Determine if this request is a postback or initial request
if (restoreViewSupport.isPostback(facesContext))
{
if (log.isTraceEnabled())
log.trace("Request is a postback");
viewRoot = viewHandler.restoreView(facesContext, viewId);
if (viewRoot == null)
{
throw new ViewExpiredException("The expected view was not returned " + "for the view identifier: "
+ viewId, viewId);
}
restoreViewSupport.processComponentBinding(facesContext, viewRoot);
}
else
{
...
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
16 years