[ 
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)

Reply via email to