3

I notice that, on Jetty (Servlet container), by default, if there is an error, the entire Stack backtrace is sent to the browser, which isn't so good for the live environment.

So I have created a little "servlet-error.html" file and included it in my web app and referenced it from the web.xml.

My web.xml looks like:

<web-app>
  ..
  <error-page>
    <error-code>500</error-code>
    <location>/servlet-error.html</location>
  </error-page>
  <error-page>
    <error-code>503</error-code>
    <location>/servlet-error.html</location>
  </error-page>
</web-app>

The WAR file looks like:

servlet-error.html
WEB-INF/web.xml
...

When I don't have the <error-page> section then I get the standard Jetty error (with backtrace), when I have it then I just get a white page in Firefox, and a standard browser error message in Chrome. There are no errors in the Jetty logs like "servlet-error.html could not be found".

I have tried changing the web.xml from /servlet-error.html to /servlet-error-xxx.html and there was no change (= white page, and no error in Jetty log). So I suspect it can't find by HTML file.

Additional information: The application is written in Wicket, the application is in Wicket "deployment mode", the exception causing the error is being thrown in the constructor of the Application (which seems to bypass Wicket's error handling and hiding of the exception backtrace in deployment mode?). The wicket application is being included via a <servlet> not a <filter>.

P.S. This Jetty is behind an Apache, so is this even the right way to handle this, or should I add something to the Apache config, i.e. "if Jetty returns != 200 then ignore what Jetty returns and instead display this error page..."

Edit: I have corrected the original reason for the error (i.e. the app now works without error) and now I can surf to http://mydomain.com/context-root/servlet-error.html, whereas before I would get the 500 error if I surf to that static HTML page. I see that I have in my web.xml:

<servlet-mapping>
  <servlet-name>my-app</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

I suspect that, when Jetty tries to execute the normal request, sees the error, then it tries to fetch the servlet-error.html page, which it also fetches by using the web.xml which falls again into trying to go to the application, which again generates the error.. And presumably to stop an infinite loop, it just displays a blank page to the browser, although something in the log would be nice!

But I'm still not sure what the right way to solve it is....

I added the following, but it didn't help.

<servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>*.html</url-pattern>
</servlet-mapping>
Adrian Smith
  • 17,236
  • 11
  • 71
  • 93

2 Answers2

1

Update: No, even this doesn't work. Now CSS files etc like /resources/com.myapp.MyPage/styles.css aren't served by Wicket (they return the startpage in HTML instead) probably because of the path info being null etc. I hate it, why can't I just install a Java app and now have Exceptions printed to the browser, why can't it just work!?

Original answer: The solution is to replace the Wicket servlet mapping with:

<servlet-mapping>
  <servlet-name>my-app</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

I.e. change /* into /; but leave the error directives and the *.html rule alone.

The reason is: this answer gives the order/priority in which <url-pattern>s are matched (alas the links to the servlet specification don't seem to work any more):

  1. A string beginning with a ‘/’ character and ending with a ‘/*’ suffix is used for path mapping.
  2. A string beginning with a ‘*.’ prefix is used as an extension mapping.
  3. A string containing only the ’/’ character indicates the "default" servlet of the application. In this case the servlet path is the request URI minus the context path and the path info is null.
  4. All other strings are used for exact matches only.

I need the "match *.html" rule to be obeyed in preference to the "send all requests to Wicket" rule. Both /* and / match all requests, but the former is the first rule (obeyed in preference to *.html) whereas the latter is the third rule (the *.html match is obeyed in preference).

Community
  • 1
  • 1
Adrian Smith
  • 17,236
  • 11
  • 71
  • 93
1

Is this only for errors in the Wicket application constructor? That is handled by Jetty.

Errors in Wicket pages go to the Page which you can specify in IApplicationSettings (in the application constructor):

IApplicationSettings settings = getApplicationSettings();
settings.setAccessDeniedPage(AccessDeniedPage.class);
settings.setPageExpiredErrorPage(PageExpiredPage.class);
settings.setInternalErrorPage(InternalErrorPage.class);

Jetty error pages can be set in the web.xml file:

Error code example:

<error-page>
  <error-code>404</error-code>
  <location>/jspsnoop/ERROR/404</location>
</error-page>

Exception example:

<error-page>
  <exception-type>java.io.IOException</exception-type>
  <location>/jspsnoop/IOException</location>
</error-page>

Source: Jetty Wiki

Daan
  • 9,984
  • 2
  • 30
  • 36
  • Hi, yes this is about errors from the Wicket application constructors, which are handled by Jetty. I don't know how to get Jetty to display my custom error page in the browser (e.g. static HTML) rather than displaying the stack backtrace in the browser (which could contain too much information e.g. SQL statements or something.) – Adrian Smith Mar 24 '11 at 13:27
  • Thanks for the information. I have already tried that (see question), do you know why it doesn't work? – Adrian Smith Mar 25 '11 at 17:50
  • Have you tried the latest Jetty version? What if you move the error pages to a subdirectory in the war file (e.g. /error/servlet-errror.html)? The extra servlet-mapping is not necessary. You could try to rename your servlet-error.html file to servlet-error.jsp? – Daan Mar 26 '11 at 14:50
  • The problem is that the request to the "servlet-error.html" goes into the standard Servlet which is the Wicket Servlet. It is exactly this Servlet which is causing the error in the first place, and therefore in that case the "servlet-error.html" can never be displayed. – Adrian Smith Mar 28 '11 at 10:25
  • Maybe add a different servlet to serve the error pages? Just an idea... I'm a little out of options :-). If the Wicket Application is running correctly, the right error pages are shown. It should not happen that often that your WebApplication subclass is broken? – Daan Mar 28 '11 at 17:54
  • Yes it's specifically about the case when the Wicket Application cannot be initialized (constructor throws an Exception). That could happen, and if that happens, the correct error page should be displayed. Adding another Servlet would be a great idea, but Wicket is configured to accept all requests, so all requests (incl. the error request) go to Wicket, even if there is another Servlet in the config file. – Adrian Smith Mar 30 '11 at 19:55