geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Blevins <david.blev...@visi.com>
Subject Re: InvocationResult
Date Sun, 24 Aug 2003 10:42:11 GMT
On Sat, Aug 23, 2003 at 11:01:21PM -0700, Jeremy Boynes wrote:
> > From: Dain Sundstrom [mailto:dain@coredevelopers.net] 
> > I think you missed the best point in this email
> Maybe, but I don't follow your example...
> 
> > 
> > On Saturday, August 23, 2003, at 02:31 PM, David Blevins wrote:
> > 
> > > We actually do wrap exceptions though.
> > >   - If the bean throws a checked exception, we wrap it with 
> > a special
> > > exception type.  When the client side get the exception, it 
> > pulls out 
> > > the nested exception and throws it.
> > >   - If the bean throws an unchecked exception, we wrap it in a 
> > > different exception (InvalidateReferenceException).  When 
> > the client 
> > > get's one of those, the proxy is invalidated as the bean 
> > was garbage 
> > > collected, the nested exception is then thrown which will be a 
> > > RemoteException/EJBException/TransactionRolledbackException/etc.
> > 
> > So in the CallBackInterceptor you do something like this:
> > 
> >      try {
> >          return new 
> > SimpleInvocationResult(callbackMethod.invoke(instance, callbackArgs));
> >      } catch (IllegalAccessException e) {
> >          // This method is using the Java language access 
> > control and the
> >          // underlying method is inaccessible.
> >          throw new EJBException(e);
> >      } catch (InvocationTargetException e) {
> >          // unwrap the exception
> >          throw new ApplicationException(e.getTargetException();
> >      }
> > 
> > 
> > Then later in the chain, if you want to distinguish the 
> > ApplicationException from the container exception just catch 
> > ApplicationException specifically, so for your example you would have 
> > this:
> > 
> >      boolean threwApplicationException = false;
> >      try {
> >          return getNext().invoke(invocation);
> >      } catch (ApplicationException e) {
> >          threwSystemException = true;
> >          throw e;
> >      } finally {
> >          // this invocation is done so remove the reference to the 
> > context
> >          EJBInvocationUtil.putEnterpriseContext(invocation, null);
> >          if (threwApplicationException) {
> >              // invocation threw an application exception so the pool
> >              // needs to dispose of the context
> >              pool.remove(ctx);
> >          } else {
> >              // return the context to the pool
> >              pool.release(ctx);
> >          }
> >      }
> > 
> > 
> > I think this is much cleaner and we don't have to inspect the result 
> > for the exceptional cases.  In the client container you catch the 
> > ApplicationException and throw the root cause.
> > 
> 
> Doesn't this need to be:
> 
>   boolean threwSystemException = false;
>   try {
>     return getNext().invoke(invocation);
>   } catch (InvalidateReferenceException e) {
>     threwSystemException = true;
>     throw e;
>   } catch (Exception e) {
>     threwSystemException = true;
>     throw e;
>   } catch (Error e) {
>     threwSystemException = true;
>     throw e;
>   } finally {
>     EJBInvocationUtil.putEnterpriseContext(invocation, null);
>     if (threwSystemException) {
>       // invocation threw a system exception so the pool
>       // needs to dispose of the context
>       pool.remove(ctx);
>     } else {
>       // return the context to the pool
>       pool.release(ctx);
>     }
>   }
> 
> You still need to ensure that the context gets disposed of if there was
> a Exception thrown by an interceptor, leaving you with the catch blocks.
> So you still have multiple return paths:
> * normal result
> * ApplicationException being thrown
> * InvalidateReferenceException being thrown
> * Exception from an Interceptor
> * Error from an Interceptor
> 


You only need to catch a specific exception type when you need to do something unique.  The
above block could be written as:

try {
    InvocationResult r = getNext().invoke(invocation);
    pool.release(ctx);
    return r;
} catch (Throwable t) {
    pool.remove(ctx);
    throw t;
} finally {
    EJBInvocationUtil.putEnterpriseContext(invocation, null);
}



-David

Mime
View raw message