Missed PreDestroy calls

If EJB instance, other than Singleton, throws system exception, which is non application runtime exception, then EJB Container immediately discards the instance without calling @PreDestroy method.

This is not a problem if calling @PreDestroy is not essential to an application. If it is, then it was proposed to provide additional application pool of resources or beans and periodically clean up abandoned resources or beans. We do it other way.

We augment EJB class with a kind of ExeptionHandler

@Stateless
public class BeanWithCleanupMechanism {
   ...
   @PreDestroy
   private void destroy(){
      //clean up
   }
   ...
   @AroundInvoke
   private Object exceptionHandling(InvocationContext ctx){
      try {
         return ctx.proceed();
      } catch ( ... e ) {
         //catch all expected application runtime exceptions 
         //and just rethrow it
         throw e;
      } catch ( RuntimeException e ) {
         //e is a system exception
         destroy();
         //rethrow exception, instance will be discarded
         //but instance is already clean
         throw e;
      }
   }
   ...
}

It is just Interceptor listening for system exceptions.

Catching all expected runtime application exceptions requires knowing these exceptions. Instead of it, all runtime exceptions can be caught and checked via reflection if annotation @ApplicationException is present in an exception’s class.

This @AroundInvoke can be part of a separate Interceptor class as well. Remember though: this @AroundInvoke method should be called as the last in a chain of interceptors

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: