Resteasy, handling and logging of WebApplicationException
jrinderle May 28, 2009 1:07 PMResteasy logs a stracktrace for all WebApplicationExceptions, which is not what I was expecting. My expectation was that Resteasy would catch this exception and return an appropriate response, but not log the exception. This creates a lot of output in the server logs.
* What is the most appropriate way to specify a response status? I could return Response but it seems cleaner to return a specific type and throw WebApplicationException for errors.
I created the following test case:
@GET @Path("/status/{code}") public String getStatus(@PathParam("code") int statusCode) { throw new WebApplicationException(statusCode); }
No matter what code I specify, the exception stack trace is logged to STDERR and I get the JBossWeb default error page back (even if I modify the code to specify no content).
* This behavior caused me to question my understanding. Should I not specify a response status by throwing a WebApplicationException? Should I instead return Response or use a custom exception with an exception mapper? In a production environment I do not need to log a stack trace for 401, 404, etc.
* Is it possible to disable the default error page and return an empty response? I tried changing the test case to
throw new WebApplicationException(Response.noContent().status(statusCode).build());but I still get default error page.
* I was also surprised to see the exception logged to STDERR. The documentation says that Resteasy uses slf4j configured or log4j. Perhaps I have something configured incorrectly?
I have tested this behavior with Resteasy 1.0.2GA and 1.1RC2. I am running on JBoss 4.2.3.GA.
When I request this resource with /status/401, I get the following response (output is from curl).
< HTTP/1.1 401 Unauthorized < Date: Thu, 28 May 2009 16:36:38 GMT < Server: Apache < Content-Length: 948 < Content-Type: text/html;charset=utf-8 * Connection #0 to host localhost left intact * Closing connection #0 <html><head><title>JBossWeb/2.0.1.GA - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 401 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>This request requires HTTP authentication ().</u></p><HR size="1" noshade="noshade"><h3>JBossWeb/2.0.1.GA</h3></body></html>
And the following exception is logged (I sanitized my class and package name, line 74 corresponds to the exception thrown above):
2009-05-28 12:38:42,883 ERROR [STDERR] 147486 [ajp-127.0.0.1-8009-11] ERROR org.jboss.resteasy.core.SynchronousDispatcher - failed t o execute 2009-05-28 12:38:42,883 ERROR [STDERR] javax.ws.rs.WebApplicationException 2009-05-28 12:38:42,883 ERROR [STDERR] at my.test.app.MyResource.getSessionDetails(MyResource.ja va:74) 2009-05-28 12:38:42,883 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 2009-05-28 12:38:42,884 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 2009-05-28 12:38:42,884 ERROR [STDERR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 2009-05-28 12:38:42,884 ERROR [STDERR] at java.lang.reflect.Method.invoke(Method.java:597) 2009-05-28 12:38:42,884 ERROR [STDERR] at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:119) 2009-05-28 12:38:42,884 ERROR [STDERR] at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:211) 2009-05-28 12:38:42,884 ERROR [STDERR] at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:176) 2009-05-28 12:38:42,884 ERROR [STDERR] at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:166) 2009-05-28 12:38:42,884 ERROR [STDERR] at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356) 2009-05-28 12:38:42,884 ERROR [STDERR] at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:160) 2009-05-28 12:38:42,885 ERROR [STDERR] at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispat cher.java:113) 2009-05-28 12:38:42,885 ERROR [STDERR] at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispat cher.java:69) 2009-05-28 12:38:42,885 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) 2009-05-28 12:38:42,885 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.j ava:290) 2009-05-28 12:38:42,885 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 2009-05-28 12:38:42,885 ERROR [STDERR] at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) 2009-05-28 12:38:42,885 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.j ava:235) 2009-05-28 12:38:42,885 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 2009-05-28 12:38:42,886 ERROR [STDERR] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) 2009-05-28 12:38:42,886 ERROR [STDERR] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 2009-05-28 12:38:42,886 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.ja va:182) 2009-05-28 12:38:42,886 ERROR [STDERR] at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84) 2009-05-28 12:38:42,886 ERROR [STDERR] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 2009-05-28 12:38:42,886 ERROR [STDERR] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 2009-05-28 12:38:42,886 ERROR [STDERR] at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java: 157) 2009-05-28 12:38:42,886 ERROR [STDERR] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 2009-05-28 12:38:42,886 ERROR [STDERR] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262) 2009-05-28 12:38:42,887 ERROR [STDERR] at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:437) 2009-05-28 12:38:42,887 ERROR [STDERR] at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:366) 2009-05-28 12:38:42,887 ERROR [STDERR] at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446) 2009-05-28 12:38:42,887 ERROR [STDERR] at java.lang.Thread.run(Thread.java:619)
SynchronousDispatcher.java:324:
if (!(wae instanceof NoLogWebApplicationException)) logger.error("failed to execute", wae);
My web.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <context-param> <param-name>resteasy.scan</param-name> <param-value>true</param-value> </context-param> <listener> <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> </listener> <servlet> <servlet-name>RESTeasy</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> </servlet> <servlet-mapping> <servlet-name>RESTeasy</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
Thank you for your help!