[ https://issues.apache.org/jira/browse/OWB-1234?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Mark Struberg reassigned OWB-1234: ---------------------------------- Assignee: Mark Struberg > generic classes are not correctly proxied when bridge methods are involved > -------------------------------------------------------------------------- > > Key: OWB-1234 > URL: https://issues.apache.org/jira/browse/OWB-1234 > Project: OpenWebBeans > Issue Type: Bug > Components: Interceptor and Decorators > Affects Versions: 2.0.4 > Reporter: Alexander Zapletal > Assignee: Mark Struberg > Priority: Major > > Proxies generated by _NormalScopeProxyFactory_ do not contain (overriding) > proxy methods for bridge methods, because bridge methods are generally > ignored by the proxy generation, see > _AbstractProxyFactory.unproxyableMethod()_ and > _ClassUtil.addNonPrivateMethods()_ . > (See also OWB-923) > But this can lead to wrong proxies: > {code:java} > interface Contract { > void doIt(Integer param); > } > {code} > {code:java} > public class BaseBean<T extends Number> { > public void doIt(T param) { > } > } > {code} > {code:java} > @ApplicationScoped > public class MyBean extends BaseBean<Integer> implements Contract { > } > {code} > When compiling this code the compiler performs type erasure and needs to > generate a bridge method. The generated byte code corresponds (roughly) to > the following code: > {code:java} > public class BaseBean { > public void doIt(Number param) { > } > } > {code} > {code:java} > public class MyBean { > // bridge method! > public void doIt(Integer param) { > super.doIt(param); > } > } > {code} > _NormalScopeProxyFactory_ generates a proxy class that (roughly) corresponds > to the following code: > {code:java} > public class MyBean$$OwbNormalScopeProxy extends MyBean { > > public void doIt(Number var1) { > ((MyBean)this.owbContextualInstanceProvider.get()).doIt(var1); > } > } > {code} > But when we now call, for instance, _doIt(4711)_ on an injected instance of > _Contract_ , we actually call _MyBean.doIt(Integer)_ and thereby we bypass > the proxy! > {code:java} > @Inject Contract handler; > handler.doIt(4711) > {code} > Reason: When _NormalScopeProxyFactory_ generated the proxy for _MyBean,_ it > found the following two methods (amongst others): > {code:java} > void doIt(Number var1) // inherited from BaseBean > void doIt(Integer var1) // bridge method > {code} > Since _NormalScopeProxyFactory_ ignores bridge methods, it only generated a > proxy method for _doIt(Number)_ . This method *overloads* > _MyBean.doIt(Integer)_ , it does not *override* it. So, _handler.doIt(4711)_ > actually calls _MyBean.doIt(Integer)_ . > > *IMPORTANT NOTE:* There is a quite simple workaround for this problem: Just > implement the bridge method yourself. I.e. in the example above use the > following implementation > {code:java} > @ApplicationScoped > public class MyBean extends BaseBean<Integer> implements Contract { > @Override > public void doIt(Integer param) { > super.doIt(param); > } > } > {code} > Now, the method _doIt(Integer)_ is not a bridge method anymore and > _NormalScopeProxyFactory_ will generate a proxy method for it. -- This message was sent by Atlassian Jira (v8.3.4#803005)