geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jeremy Boynes" <jer...@coredevelopers.net>
Subject RE: InvocationResult
Date Sun, 24 Aug 2003 06:01:21 GMT
> 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

The other thing that always using the InvocationResponse allows is the
addition of meta-information with a non-normal response. Yes, it would
be possible to include it in
ApplicationException/InvalidateReferenceException but that doesn't seem
like the right place.


--
Jeremy



Mime
View raw message