[
https://issues.apache.org/jira/browse/OWB-1465?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Richard Zowalla updated OWB-1465:
---------------------------------
Description:
Since bridge methods are materialized on subclass proxies (OWB-1234/OWB-923),
{{NormalScopeProxyFactory.delegateNonInterceptedMethods}} re-declares the JVM
bridge methods of the proxied class. However, the generated method's modifiers
are masked with
{code:java}
int targetModifiers = delegatedMethod.getModifiers() & (Modifier.PROTECTED |
Modifier.PUBLIC | MODIFIER_VARARGS);
{code}
which strips {{ACC_BRIDGE}} (and {{{}ACC_SYNTHETIC{}}}). For a bean
implementing a generic interface, e.g.
{code:java}
public interface GenericParameterInterface<T extends CustomBaseType> {
String consume(T instance);
}
public class SpecificParameterClass implements
GenericParameterInterface<CustomType> {
@Override
public String consume(CustomType instance) { ... }
}
{code}
the normal scope proxy ends up exposing *two regular methods*
{{consume(CustomType)}} and {{consume(CustomBaseType)}} — on the proxied class
itself the latter is flagged as such.
*Impact:* Expression language implementatio by preferring the non-bridge
variant (seeTomcat's {{org.apache.el.util.ReflectionUtil}} /
{{{}jakarta.el.Util{}}}, which tie-break via {{{}Method.isBridge(){}}}).
Against such a proxy both candidates look ling e.g. {{{}#{bean.consume(x){}}}}
fails with
{noformat}
jakarta.el.MethodNotFoundException: Unable to find unambiguous method:
Bean$$OwbNormalScopeProxy0.consume(...)
{noformat}
Observed in practice with MyFaces action means implementing generic interfaces
(TomEE 11 M4 / OWB 4.1.0). This worked with OWB 4.0.x, which did not re-declare
bridge methods on proxies.
{{InterceptorDecoratorProxyFactory}} is *not* affected: it skips bridge methods
entirely ({{{}unproxyableMethod{}}}), so
the properly flagged bridge is inherited fr
*Test case + fix attempt: https://github.com/apache/openwebbeans/pull/140*
was:
Since bridge methods are materialized on subclass proxies (OWB-1234/OWB-923),
{{NormalScopeProxyFactory.delegateNonInterceptedMethods}} re-declares the JVM
bridge methods of the proxied class. However, the generated method's modifiers
are masked with
{code:java}
int targetModifiers = delegatedMethod.getModifiers() & (Modifier.PROTECTED |
Modifier.PUBLIC | MODIFIER_VARARGS);
{code}
which strips {{ACC_BRIDGE}} (and {{{}ACC_SYNTHETIC{}}}). For a bean
implementing a generic interface, e.g.
{code:java}
public interface GenericParameterInterface<T extends CustomBaseType> {
String consume(T instance);
}
public class SpecificParameterClass implements
GenericParameterInterface<CustomType> {
@Override
public String consume(CustomType instance) { ... }
}
{code}
the normal scope proxy ends up exposing *two regular methods*
{{consume(CustomType)}} and {{consume(CustomBaseType)}} — on the proxied class
itself the latter is flagged as such.
*Impact:* Expression language implementatio by preferring the non-bridge
variant (seeTomcat's {{org.apache.el.util.ReflectionUtil}} /
{{{}jakarta.el.Util{}}}, which tie-break via {{{}Method.isBridge(){}}}).
Against such a proxy both candidates look ling e.g. {{{}#{bean.consume(x){}}}}
fails with
{noformat}
jakarta.el.MethodNotFoundException: Unable to find unambiguous method:
Bean$$OwbNormalScopeProxy0.consume(...)
{noformat}
Observed in practice with MyFaces action means implementing generic interfaces
(TomEE 11 M4 / OWB 4.1.0). This worked with OWB 4.0.x, which did not re-declare
bridge methods on proxies.
{{InterceptorDecoratorProxyFactory}} is *not* affected: it skips bridge methods
entirely ({{{}unproxyableMethod{}}}), so
the properly flagged bridge is inherited fr
*Test case* (fails on current master with {second test documents the correct
interceptor proxy behaviour):
[https://github.com/rzo1/openwebbeans/tree/n]
(commit [3169f8faf|https://github.com/rzo1/openwebbeans/commit/3169f8faf])
*Suggested fix:* preserve the bridge flag in
{{{}NormalScopeProxyFactory.delegateNonInterceptedMethods{}}}, e.g.
{code:java}
int targetModifiers = delegatedMethod.getMo
& (Modifier.PROTECTED | Modifier.PUBLIC | MODIFIER_VARARGS |
MODIFIER_BRIDGE | MODIFIER_SYNTHETIC);
{code}
with {{MODIFIER_BRIDGE = 0x0040}} / {{MODIF{{java.lang.reflect.Modifier}}
constantsexist for these).
> NormalScopeProxyFactory drops the ACC_BRIDGE flag from re-declared bridge
> methods, breaking EL overload resolution
> ------------------------------------------------------------------------------------------------------------------
>
> Key: OWB-1465
> URL: https://issues.apache.org/jira/browse/OWB-1465
> Project: OpenWebBeans
> Issue Type: Bug
> Affects Versions: 4.1.0
> Reporter: Richard Zowalla
> Priority: Major
> Labels: pull-request-available
>
> Since bridge methods are materialized on subclass proxies (OWB-1234/OWB-923),
> {{NormalScopeProxyFactory.delegateNonInterceptedMethods}} re-declares the JVM
> bridge methods of the proxied class. However, the generated method's
> modifiers are masked with
> {code:java}
> int targetModifiers = delegatedMethod.getModifiers() & (Modifier.PROTECTED |
> Modifier.PUBLIC | MODIFIER_VARARGS);
> {code}
> which strips {{ACC_BRIDGE}} (and {{{}ACC_SYNTHETIC{}}}). For a bean
> implementing a generic interface, e.g.
> {code:java}
> public interface GenericParameterInterface<T extends CustomBaseType> {
> String consume(T instance);
> }
> public class SpecificParameterClass implements
> GenericParameterInterface<CustomType> {
> @Override
> public String consume(CustomType instance) { ... }
> }
> {code}
> the normal scope proxy ends up exposing *two regular methods*
> {{consume(CustomType)}} and {{consume(CustomBaseType)}} — on the proxied
> class itself the latter is flagged as such.
> *Impact:* Expression language implementatio by preferring the non-bridge
> variant (seeTomcat's {{org.apache.el.util.ReflectionUtil}} /
> {{{}jakarta.el.Util{}}}, which tie-break via {{{}Method.isBridge(){}}}).
> Against such a proxy both candidates look ling e.g.
> {{{}#{bean.consume(x){}}}} fails with
> {noformat}
> jakarta.el.MethodNotFoundException: Unable to find unambiguous method:
> Bean$$OwbNormalScopeProxy0.consume(...)
> {noformat}
> Observed in practice with MyFaces action means implementing generic
> interfaces (TomEE 11 M4 / OWB 4.1.0). This worked with OWB 4.0.x, which did
> not re-declare bridge methods on proxies.
> {{InterceptorDecoratorProxyFactory}} is *not* affected: it skips bridge
> methods entirely ({{{}unproxyableMethod{}}}), so
> the properly flagged bridge is inherited fr
> *Test case + fix attempt: https://github.com/apache/openwebbeans/pull/140*
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)