3

From this post I have thought of another question I cannot seem to find the answer to on the interweb.

I have a servlet filter which detects session timeouts and redirects to an error page. Due to my fledgling java I've used try catch blocks to catch exceptions and handle them gracefully, but in a session timeout situation, the context is invalid so I don't think I've got any code I can do that with which will stop the 'viewId could not be restored' stace trace appearing in my log even though I have a filter handling it.

How can I stop the exception trace from appearing in my log? It will be monitored autoamtically in live and it will be a false positive call out to the support team for this sort of error.

Any help appreciated.

EDIT

To be more clear, my code clip is currently

public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    try {
        chain.doFilter(request, response);
    } catch (ServletException e) {
        logger.error("Caught Servlet Exception");
        Throwable rootCause = e.getRootCause();
        logger.error("Root cause is " + rootCause.toString());

        if (rootCause instanceof RuntimeException) { // This is true for any FacesException.
            logger.error("Rethrowing exception as RuntimeException" + rootCause.toString());
            throw (RuntimeException) rootCause; // Throw wrapped RuntimeException instead of ServletException.
        } else {
            throw e;
        }
    }
}

The log says:

    |STDOUT| 2011-01-19 10:40:57,803 | ERROR | [http-8080-5]: Exception in the filter chain
    javax.servlet.ServletException: viewId:/index.jsf - View /index.jsf could not be restored.
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:270)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
        at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
<snip>
        at java.lang.Thread.run(Unknown Source)
    Caused by: javax.faces.application.ViewExpiredException: viewId:/index.jsf - View /index.jsf could not be restored.
<snip>
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
        ... 21 more
    19-Jan-2011 10:40:57 org.apache.catalina.core.StandardWrapperValve invoke
    SEVERE: Servlet.service() for servlet Faces Servlet threw exception
    javax.faces.application.ViewExpiredException: viewId:/index.jsf - View /index.jsf could not be restored.
        at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:185)
<snip>
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Unknown Source)
    |STDOUT| 2011-01-19 10:40:57,803 | ERROR | [http-8080-5]: Caught Servlet Exception
    |STDOUT| 2011-01-19 10:40:57,803 | ERROR | [http-8080-5]: Root cause is javax.faces.application.ViewExpiredException: viewId:/index.jsf - View /index.jsf could not be restored.
    |STDOUT| 2011-01-19 10:40:57,803 | ERROR | [http-8080-5]: Rethrowing exception as RuntimeExceptionjavax.faces.application.ViewExpiredException: viewId:/index.jsf - View /index.jsf could not be restored.

As you can see from the code, I've caught the servlet exception in the filter, but the stack is still appearing in the log.

NEXT EDIT The complete list of filters in my web.xml is as follows:

<filter>
    <filter-name>Error</filter-name>
    <filter-class>prismClient.ErrorFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>Error</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <display-name>RichFaces Filter</display-name>
    <filter-name>richfaces</filter-name>
    <filter-class>org.ajax4jsf.Filter</filter-class>
</filter>
<filter-mapping>
    <filter-name>richfaces</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
</filter-mapping>
Community
  • 1
  • 1
volvox
  • 3,014
  • 16
  • 51
  • 80

3 Answers3

4

Filters are executed in the order they are defined in the web.xml file. In your case, it looks like the jfaces filter is executed first and logging the stack trace before your custom filter has a chance to filter it out. Try making your filter entry in web.xml the first one.

EDIT

It's possible that some other filter in the chain is logging the ServletException before it throws it. In the stack trace you posted, it looks like there is a filter for ajax4jsf that may be logging the ServletException. Do you have the source for this? How may filters are in your web.xml?

EDIT 2

It looks like ajax4jsf is catching ServletException and logging an error message before throwing it back out. I suggest you get the source for the version of ajax4jsf that you're using and look at the lines in the stack trace (BaseXMLFilter.java line 178 and BaseFilter.java line 290) and search for logging statements. If you find them, you can either remove them from the source and rebuild ajax4jsf, or disable the category in your logging configuration file. I don't recommend the latter, because you will miss other errors that may occur in the filter.

If that is not the source of the error message, then I'm afraid I've run out of ideas.

Jason Day
  • 8,809
  • 1
  • 41
  • 46
  • But unfortunately not working. I put the filter entries (`filter` and `filter-mapping`) before the RichFaces Filter and I still get a stacktrace in the log when the session timesout. I use Log4J in a really standard way. – volvox Jan 19 '11 at 16:42
  • Jason many thanks for your persistence. I've edited my post to include the full, ordered list of my filters. I see the al4sf filter you mentioned, but I'm under the impression I have to have it in there. Configuration on the other hand is a different kettle of fish - this one I believe is defined as recommended in richfaces setup documentation - do feel free to suggest how you see it would be better configured based on my OP. – volvox Jan 20 '11 at 12:29
1

Possibly because you rethrow the exception, whatever is logging it is still getting it. Even though you're blocking the ServletException out and rethrowing the RunTimeException (which ViewExpiredException is), something higher in the filter chain may be rewrapping it.

Do any of the logs you write in this method also show up in the log before the stacktrace?

Don Roby
  • 40,677
  • 6
  • 91
  • 113
  • Thanks for your words. In answer to your question, no - the stack trace is always first out. – volvox Jan 19 '11 at 12:44
  • Then my conjecture about the rethrow being the problem must be wrong. Unfortunately I've got no further ideas at this point. – Don Roby Jan 19 '11 at 12:48
0

Did you try writing a Session filter yourself? Find a nice example here.

Ilya Saunkin
  • 18,934
  • 9
  • 36
  • 50
  • I did write the filter myself. Your example is essentially what I've already written (except I haven't limited mine to the http protocol). I've edited my post to be more specific. – volvox Jan 19 '11 at 11:18
  • you don't handle the ViewExpiredException there. – Ilya Saunkin Jan 19 '11 at 11:38
  • No but I handle it as a RunTimeException which is what it is. – volvox Jan 19 '11 at 12:46
  • yeah, I see that, but you just throw it again! And it's not instanceof RuntimeException, it's a subclass of RuntimeException. – Ilya Saunkin Jan 19 '11 at 12:57
  • @Elijah: an instance of a subclass of RuntimeException _is_ an instanceof RuntimeException. – László van den Hoek May 09 '11 at 13:48
  • My point was that he doesn't handle it specifically. It's like catching an Exception and throwing it again: this way you wouldn't really be able so see what sort of problem you just had. – Ilya Saunkin May 09 '11 at 14:25