users@jersey.java.net

Re: [Jersey] ContainerResponseFilter is not suitable for cleanup job

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 12 Feb 2009 10:49:43 +0100

On Feb 12, 2009, at 1:05 AM, Roytman, Alex wrote:

> Hello Paul, everyone,
>
> One of the issues I was having with Jersey is a lack of reliable
> mechanism to cleanup any “closeable things” after request is done.
>
> First let me clear up terminology – since Resource have a special
> meaning in JAX-RS I will call “closeable” what we typically call a
> resource in java (i.e. database connection, persistence manager,
> stream ….) - Anything which needs explicit closing after use.
>
> One mechanizm which sems to work reliable is @PostConstruct and
> @PreDestroy but it is not very transparent and can not be used with
> injected “closeable” because injection happens implecetly while
> @PreDestroy must be declared explicetly so there is plenty of room
> for mistakes
>

Note that @PostConstruct and @PreDestroy are the preferred approach
for Java EE. Ideally the injector would create an instance of
something to inject that is managed by the IoC framework. The class of
the injected instance would implement a method annotated with
@PreDestroy. Then the class that have the thing injected into it does
not have to manage it.



> Another approach is to cleanup in ContainerResponseFilter – have any
> injected or otherwise instantiated “closeable” register themselves
> in HttpContext.properties and have a ContainerResponseFilter to do
> clean up job.
> Unfortunately it does not work because an exception in Resource
> method or in one of prior ContainerResponseFilter registered with
> Jersey will terminate filter chain leaving “cleaseable” unclosed.
>

> It is not just that it does not work currently, I think it is not
> the best mechanism for cleanup job because exception handling logic
> of filter chain might be very well at odds with the need for
> gauranteed invocation of cleanup filters.
>

I agree, in general it is because even if we support a try/catch per
response filter, only responses mapped from exceptions will be
processed. It will always be possible to break the chain if an
exception cannot be mapped to a response.


> There is JDOResourceFilterFactory but it probably suffers the same
> issues and probably cannot take care of “closeables” fields in
> Resource since it will only be bound to methods if I understand
> correctly.
>
> One very strong reason for needing cleanup stage is that when
> returning StreamingOutput response Resource method has no way to
> clean up after itself only container knows when to do cleanup!
> Without @PreDestroy entire use case of StreamingOutput is close to
> usless and @PreDestroy is pretty error prone. I can just see
> inexperienced developers either closing “closeable” inside Resource
> method and having StreamingOutput blow up on them or much worse –
> frustrated they just leave them open (what the hell) untill whole
> app runs out of database connections or whatever closeable they are
> using.
>
>
> I realize that Jersey is not a general purpose IoC framework but it
> seems to me that ability to create or inject closeable with some
> guarantee of cleanup is just so core to any service that I do not
> see how it can be relegated to some other optional add-ons. To me it
> should be even defined in specs J
>

WebBeans :-) which is planned for Java EE 6.


> I would greatly appreciate your feedback and suggestions

Here is a proposal:

1) We defined a standard request property whose value is Set<Closeable>;

2) We define an injectable provider to manage the property in 1).

3) In the finally block of the Web application after the request as
been processed we iterate through the Set<Closeable> in 1).

I believe this could also be useful for the MultipartMime support as
well to clean up body parts cached on disk.

Paul.