Status: New
Owner: ----

New issue 684 by [email protected]: Possibility to save state of InterceptorStackCallback in MethodInvocation implementation
http://code.google.com/p/google-guice/issues/detail?id=684

When writing a MethodInterceptor the state of the MethodInvocation passed in by Guice is only valid before and after proceed has been called. And before the invoke method returns.

i.e.

@Override public Object invoke(final MethodInvocation invocation) throws Throwable {
   // invocation valid
Object result = invocation.proceed(); // invocation changes for the duration of the proceed call
   // invocation valid
   return result;
   // invocation changes due to return
}

The reason for this is the use of the mutable "index" field in the InterceptedMethodInvocation class.

The implementation of "proceed()" recursively passes itself to each of the interceptors. Effectively "index" is working as a stack pointer.

The consequence of this is that I cannot keep a reference to the MethodInvocation object and use it somewhere else. For example, I want to write an method interceptor that executes the intercepted method in a different thread. An immutable implementation of MethodInvocation would be preferable.

For example copying the InterceptedMethodInvocation before each invocation would solve this problem by making the MethodInvocation more like an immutable object. Like this:

  private class InterceptedMethodInvocation implements MethodInvocation {

    final Object proxy;
    final Object[] arguments;
    final MethodProxy methodProxy;

public InterceptedMethodInvocation(final Object proxy, final MethodProxy methodProxy,
        final Object[] arguments) {
        this(proxy, methodProxy, arguments, -1);
    }

public InterceptedMethodInvocation(final Object proxy, final MethodProxy methodProxy,
            final Object[] arguments, int index) {
      this.proxy = proxy;
      this.methodProxy = methodProxy;
      this.arguments = arguments;
      this.index = index;
    }

    public Object proceed() throws Throwable {
      try {
        int nextIndex = index + 1;
        return nextIndex == interceptors.length
            ? methodProxy.invokeSuper(proxy, arguments)
: interceptors[nextIndex].invoke(new InterceptedMethodInvocation(proxy, methodProxy, arguments, nextIndex));
      } catch (final Throwable t) {
        pruneStacktrace(t);
        throw t;
      }
    }

    public Method getMethod() {
      return method;
    }

    public Object[] getArguments() {
      return arguments;
    }

    public Object getThis() {
      return proxy;
    }

    public AccessibleObject getStaticPart() {
      return getMethod();
    }
  }

--
You received this message because you are subscribed to the Google Groups 
"google-guice-dev" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-guice-dev?hl=en.

Reply via email to