[weld-dev] Bridge methods & proxies & interceptors

Marko Lukša marko.luksa at gmail.com
Fri Sep 7 05:19:16 EDT 2012


Hey all.

I've been working on https://issues.jboss.org/browse/WELD-1162 and need 
your opinion.

Say we have:

public interface Foo<T> {
    void doSomething(T t);
}
public interface StringFoo extends Foo<String> {}
public class StringFooImpl implements StringFoo {}

and

@Inject StringFoo stringFoo;

The proxy created by Weld is a subclass of StringFooImpl and therefore 
has two declared methods:

void doSomething(Object o) { doSomething((String) o); }
void doSomething(String) {...}

However, when StringFooImpl is a session bean, with StringFoo as its 
local interface, the proxy is a subclass of Object and therefore the 
proxy only has the following declared method:

void doSomething(Object o);

In both cases, when a client invokes stringFoo.doSomething("foo"), the 
method doSomething(Object) is invoked. But there's a difference in what 
happens next:

  * In the non-ejb version, the bridge method then immediately invokes
    doSomething(String) and only then is the proxy's method handler
    invoked. The handler is therefore dealing with the method
    doSomething(*String*)
  * in the EJB version, doSomething(Object) is not a bridge method, and
    so the method handler is invoked directly and it (the handler) is
    operating on doSomething(*Object*).

In the second case, this ultimately means that Weld will check whether 
doSomething(Object) is intercepted. It isn't, since 
Beans.getInterceptableMethods() is ignoring bridge methods. The 
interceptor will not be invoked. On the other hand, in the first case, 
the interceptor _will_ be invoked, since Weld will be checking whether 
doSomething(String) is intercepted.

My initial solution was to make Beans.getInterceptableMethods() also 
return bridge methods, but now I'm thinking the actual problem is in the 
proxy itself. IMO, when creating a proxy based on an interface, we 
should also generate bridge methods on the proxy (this should be either 
done by Weld or by Javassist directly). These bridge methods should be 
perfectly normal bridge methods and should not invoke the method handler 
directly. They should simply invoke the non-bridge method and the 
non-bridge method should then invoke the method handler.

The java compiler can't add bridge methods directly to interfaces which 
require them, so it adds them to all the classes implementing the 
interface (StringFooImpl in our case). Since we are creating 
StringFoo$Proxy, which is also a class implementing an interface which 
requires bridge methods, we should add the bridge methods
to it - exactly as the java compiler would.

This would solve the interceptor problem and possibly other similar 
problems as well.

What do you think?

Marko


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/weld-dev/attachments/20120907/9cd8a67f/attachment.html 


More information about the weld-dev mailing list