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:58:11 +0100

Note that if you want to support this with the current code you can do
the following:

1) Override the ServletContainer.service method and do:

   try {
      super.service(....)
   } finally {
      Set<Closeable> s =
(Set<Closeable>)request.getAttribute("closable.set");
      if (null) return;
      for (c : s) {
         try {
            c.close();
         } catch (Exception e) {
            // log severe error
            // and keep on trucking
         }
      }
   }

and you can inject:

   @Context HttpServletRequest hr;

on your JDO injectable provider.

Paul.

On Feb 12, 2009, at 10:49 AM, Paul Sandoz wrote:

>
> 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.