users@jersey.java.net

Re: [Jersey] Resource Management through nested sub-locators

From: Martin Probst <mail_at_martin-probst.com>
Date: Tue, 9 Jun 2009 11:52:02 +0200

Pondering this a bit more and looking through the code, I noticed that
the actual Response is not constructed until after all the matching
has happened. So if one needs the session/resource/whatever to be
still open during the response building, this method will not work as
the ScarceThing will be closed after matching has happened. This again
probably depends on your use case, but if e.g. you're returning a
response that will be lazily built/streamed, this won't work (I'm
aware that Jersey will close streams, but there are other cases). So
this throws me back with a servlet filter checking if Servlet.service
throws an exception or not as the only solution, as I do now.

The way I see this error handling/resource management is that I want
to allocate resources and reliably free them. Beyond that, I also want
to be notified if request handling did not complete normally, i.e. by
throwing an unexpected exception that is neither handled within the
user code, nor a WebApplicationException or MappableContainerException
(I think, for the latter I'm not sure about its uses), so that I can
run a compensation action (rollback).

So this is possible for the resource management part by implementing a
servlet filter that will catch unhandled exceptions, and registering
allocated resources with that filter so that it can handle them with
rollback/commit correctly. But this happens outside of Jersey, so I
cannot use the nice Response.build features and similar. Also, if
someone implements an ExceptionMapper for some exception, she will
either need to tell the filter that the request still failed (if that
is the case), or we'll end up committing things that shouldn't be.

This could probably be solved by having an ErrorListener (not handler,
just listener) that will be notified if a request failed under the
aforementioned terms. Kind of like an ExceptionMapper<T>, but with the
different semantics that it's not consuming the error (so that all
listeners will be notified) and not constructing a response (which
would be left to the mappers).

This is getting more complex than I had anticipated - I guess it's a
trade off between the elegance of JAX-RS and the simplicity of plain
servlets where you'd simply have the try/finally construct.

> I am not sure, I am guessing it is if the "method" (Servlet.service
> or an EJB method) does not complete (i.e. throws an exception).

So pretty much as I do now, but sadly you loose the nice error
handling features of Jersey that way. It might also be a bit
unanticipated by users - if you have an
ExceptionMapper<WorldHasAbruptlyEnded>, your database session will be
committed even though this might not have been intended by the user -
maybe he just wanted to create a more legible error message.

I guess it's quite hard to make decisions in that area, but an
unambiguous way to communicate to the outside/framework that this
request has failed would probably be nice. I'm not sure how many
people actually really care about this, but I can see people getting
bitten by this.

Martin