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 02:09:11 GMT

> What about when a container/interceptor itself throws an error,
> this still needs to reach the client as an ordinary
> RemoteException/EJBException.
>
This would be handled by the head interceptor or proxy - kind of:
try {
  InvocationResult result = firstInterceptor.invoke()
  if (result.wasNormal) {
     return result.getResult();
  } else if (result.wasApplicationException()) {
     throw (Exception) result.getThrowable();
  } else {
     // convert system exception to EJB/Remote and throw
  }
} catch (Throwable t) {
  // problem raised by container
  // convert to EJB/Remote and throw
}

> We returned exceptions rather than throwing them in OpenEJB at
> first, just as you're proposing.  We eventually took it out
> simply because exceptions can still occur on the way back to the
> client.  So you end up catching exceptions anyway, but now your
> code is split between try/catches and some if tests on the result
> object.  Still works, but looks a little goofy.
Hmmm - goofy :-)
Right now we have (from StatelessInstanceInterceptor):
  boolean threwSystemException = false;
  try {
    return getNext().invoke(invocation);
  } catch (RuntimeException e) {
    threwSystemException = true;
    throw e;
  } catch (RemoteException e) {
    threwSystemException = true;
    throw e;
  } catch (Error e) {
    threwSystemException = true;
    throw e;
  } finally {
    // this invocation is done so remove the reference to the context
    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);
    }
  }

which gets pretty tedious in dealing with the different exit conditions from
the invoke. It could become something like:

  InvocationResult result = null;
  try {
    result = getNext().invoke(invocation);
  } finally {
    // this invocation is done so remove the reference to the context
    EJBInvocationUtil.putEnterpriseContext(invocation, null);

    if (result == null || result.wasSystemException()) {
      // 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);
    }
  }

which I think is a little less goofy (but not much).

>
> Actually, I don't see the need for an InvocationResult interface.
>  Seems like it was added for just-in-case flexibility, but after
> years of existence it still isn't getting leveraged for anything.
>  The RPCContainer interface of OpenEJB has been like this for
> years with no problems:
>
>  Object invoke(<invocation data>) Exception
>

This was how JBoss did it too before 4.x when InvocationResult was
introduced. The reason it is there is to allow meta-values to be passed back
up the interceptor stack. For example, cluster state-change information (if
a node joined or left), read-ahead information for a finder; basically any
system data that could be useful in the next invocation.

--
Jeremy


Mime
View raw message