[weld-dev] Bridge methods & proxies & interceptors

Marko Lukša marko.luksa at gmail.com
Fri Sep 7 12:08:13 EDT 2012


The test is at 
https://github.com/luksa/weld-core/commit/16604c599d6423acbc06a77160398783c370d639

Marko

On 7.9.2012 17:27, Stuart Douglas wrote:
> IMHO the correct way to deal with this is to simply make bridge 
> methods delegate to super(), which will then result in the actual 
> intercepted method being called.
>
> To be honest I thought we already did this, as we have had multiple 
> related bugs in the past. Do you have a test case that I can look at?
>
> Stuart
>
>> Marko Lukša <mailto:marko.luksa at gmail.com>
>> 7 September 2012 7:19 PM
>> 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
>>
>>
>> _______________________________________________
>> weld-dev mailing list
>> weld-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/weld-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/weld-dev/attachments/20120907/772e7c1c/attachment.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: postbox-contact.jpg
Type: image/jpeg
Size: 1249 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/weld-dev/attachments/20120907/772e7c1c/attachment.jpg 


More information about the weld-dev mailing list