users@glassfish.java.net

Re: JAX-RS error code 500 = GlassFish HTML error page

From: Jan Luehe <Jan.Luehe_at_Sun.COM>
Date: Thu, 14 Jan 2010 15:12:32 -0800

On 01/14/10 03:39 AM, Paul Sandoz wrote:
>
> On Jan 13, 2010, at 11:16 PM, Jan Luehe wrote:
>
>> On 01/13/10 01:22 PM, glassfish_at_javadesktop.org wrote:
>>>> Earlier in this thread, you mentioned a quote from
>>>> the W3C
>>>> specification for HTTP response codes in the 4xx and
>>>> 5xx ranges:
>>>>
>>>> Except when responding to a HEAD request, the
>>>> server SHOULD include
>>>> an entity containing an explanation of the error
>>>> situation.
>>>> This is where the default error page comes into the
>>>> picture.
>>>>
>>>> If you don't have any error pages configured for your
>>>> app and want to
>>>> bypass the default error page, you could do something
>>>> like this in your
>>>> servlet's service method:
>>>>
>>>> try {
>>>> // some code here
>>>> } catch (Throwable t) {
>>>> response.setStatus(500);
>>>> response.flushBuffer();
>>>> // rethrow
>>>> throw new ServletException(t);
>>>> }
>>>> ld that work for you?
>>>>
>>>
>>>
>>> I am not writing a servlet -- I am writing a JAX-RS service so that does not work for me.
>>>
>>>
>> I know, my comment was more targeted towards the Jersey integration
>> servlet, and therefore Paul.
>>
>> I'm not familiar with any Jersey implementation details, but I suspect
>> that when you output an entity body to the JAX-RS response (when
>> returning an error), this will commit the corresponding HTTP response,
>> and therefore, the web container's error page mechanism (and its
>> default error page) will be completely bypassed, even if a matching
>> error page
>> existed. In other words, the GlassFish web container won't "take over
>> the response",
>> as you put it.
>>
>
> We have specified JAX-RS and carefully implemented Jersey such that if
> one wants to map error-based status codes, when no response entity is
> declared, or map exceptions passed from Jersey to the servlet layer
> then it is possible i.e. it provides good integration with the servlet
> layer.
>
> The problem here is that GF is providing some defaults on behalf of
> the developer when no response entity and error page mapping is
> declared. IIRC App servers like WebSphere and WebLogic do not do this
> by default?
>
> Invariable any Web app deployed in production be it HTML based or
> otherwise will likely want to override the default error page behavior
> supplied by GF so I suspect the value for such default behavior is
> when developing to aid the developer so they don't state bemused at an
> empty page in the browser when a 404 or 500 status code is returned.
>
>
>> If I understood your original request correctly, you wanted to be able
>> to get the above behaviour (of GlassFish not interfering with your
>> response) *without* having to provide an entity in the JAX-RS response.
>>
>> As I mentioned earlier, the Servlet spec requires that the web
>> container use the sendError method to send 4xx and 5xx status
>> responses, so that the error mechanism may be invoked.
>
> Yes, but IIRC Servlet does not specify that default error pages should
> be returned if the client does not declare error page mappings.
>
>
>> sendError is
>> required to clear the response buffer and return the contents of the
>> error page. Note that the web container will *not* invoke sendError
>> semantics if the response has already been committed.
>>
>
> If i write a simple servlet like the following it still returns a
> default error page:
>
> public class NewServlet extends HttpServlet {
>
> @Override
> public void service(HttpServletRequest request,
> HttpServletResponse response)
> throws ServletException, IOException {
> response.setStatus(500);
> }
> }
>
>

This is indeed a bug. Calling HttpServletResponse#setStatus with an error
code correctly skips looking up any custom error pages, but still
includes the
default error page.

I've filed https://glassfish.dev.java.net/issues/show_bug.cgi?id=11441 and
already fixed it.

I like your suggestion of allowing to disable the default error page
on a per-application basis via some configuration in sun-web.xml, and have
reopened https://glassfish.dev.java.net/issues/show_bug.cgi?id=11423
(the issue
that Ryan had filed) so that it can be fixed accordingly.

Thanks,

Jan


>
>> So the trick is to ensure that the response has already been committed
>> when it is returned through the web container. Apparently, outputting
>> an entity to the JAX-RS response has this effect, but perhaps the
>> Jersey integration servlet could commit (under the circumstances
>> mentioned in this thread) the response even if no entity body has been
>> written.
>>
>
> I disagree (see above). IMHO the correct approach is to ensure that
> default error page support is switched off by default and may be
> enabled per web application (or per servlet).
>
> Paul.