> From: Dain Sundstrom [mailto:[EMAIL PROTECTED]
> 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