<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
Hey all.<br>
<br>
I've been working on <a class="moz-txt-link-freetext" href="https://issues.jboss.org/browse/WELD-1162">https://issues.jboss.org/browse/WELD-1162</a> and
need your opinion.<br>
<br>
Say we have:<br>
<br>
public interface Foo<T> {<br>
void doSomething(T t);<br>
}<br>
public interface StringFoo extends Foo<String> {}<br>
public class StringFooImpl implements StringFoo {}<br>
<br>
and<br>
<br>
@Inject StringFoo stringFoo;<br>
<br>
The proxy created by Weld is a subclass of StringFooImpl and
therefore has two declared methods:<br>
<br>
void doSomething(Object o) { doSomething((String) o); }<br>
void doSomething(String) {...}<br>
<br>
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:<br>
<br>
void doSomething(Object o);<br>
<br>
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:<br>
<ul>
<li>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(<b>String</b>)</li>
<li>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(<b>Object</b>).</li>
</ul>
<p>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. <br>
</p>
<p>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.<br>
</p>
<p>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 <br>
to it - exactly as the java compiler would.<br>
</p>
<p>This would solve the interceptor problem and possibly other
similar problems as well.<br>
</p>
What do you think?<br>
<p>Marko<br>
</p>
<p><br>
</p>
</body>
</html>