Annotations on return-overridden methods also end up on bridge methods
Vicente-Arturo Romero-Zaldivar
vicente.romero at oracle.com
Thu Nov 21 04:29:54 PST 2013
Hi Remi,
On 21/11/13 11:27, Remi Forax wrote:
> On 11/21/2013 12:20 PM, Vicente-Arturo Romero-Zaldivar wrote:
>> Hi Charles,
>>
>> Comments below.
>>
>> On 21/11/13 08:16, Charles Oliver Nutter wrote:
>>> Hey there!
>>>
>>> Sorry if this has been asked before, but I've been trying to get JRuby
>>> to compile properly on JDK8 javac and noticed a change.
>>>
>>> JDK8 generates bridge methods in cases where a child class overrides a
>>> superclass method with a more specific return type. This may have been
>>> present in JDK7 and lower, I'm not sure.
>>>
>>> What does seem to be different is that annotations attached to the
>>> hand-written override are also being attached to the bridge method.
>>>
>>> An example from JRuby...
>>>
>>> RubyBasicObject defines op_equal:
>>>
>>> public class RubyBasicObject ... {
>>> ...
>>> @Override
>>> public IRubyObject op_equal(ThreadContext context, IRubyObject
>>> obj) {
>>> return op_equal_19(context, obj);
>>> }
>>> ...
>>> }
>>>
>>> RubyMethod extends RubyObject which extends RubyBasicObject, and it
>>> also overrides op_equal with a more specific return type:
>>>
>>> public class RubyMethod extends RubyObject {
>>> ...
>>> @JRubyMethod(name = "==", required = 1)
>>> @Override
>>> public RubyBoolean op_equal(ThreadContext context, IRubyObject
>>> other) {
>>> ...
>>> }
>>>
>>> We use the JRubyMethod annotation to generate stubs for binding the
>>> Ruby class's methods at boot time. These stubs are generated by
>>> walking declared methods looking for the JRubyMethod annotation.
>>>
>>> However, on JDK8, we get an error like this:
>>>
>>> Exception in thread "main" java.lang.ClassFormatError: Duplicate
>>> method name&signature in class file
>>> org/jruby/RubyMethod$INVOKER$i$op_equal
>>>
>>> This is because JDK8's generated IRubyObject-returning bridge method
>>> also has the JRubyMethod annotation.
>>>
>>> Here's the relevant entry in the constant pool:
>>>
>>> system ~/projects/jruby $ javap -v -cp core/target/classes/
>>> org.jruby.RubyMethod
>>> Classfile
>>> /Users/headius/projects/jruby/core/target/classes/org/jruby/RubyMethod.class
>>> ...
>>> #122 = Utf8 RuntimeVisibleAnnotations
>>> #123 = Utf8 Lorg/jruby/anno/JRubyMethod;
>>> #124 = Utf8 name
>>>
>>> Here's the hand-written method plus RuntimeVisibleAnnotations:
>>>
>>> public org.jruby.RubyBoolean
>>> op_equal(org.jruby.runtime.ThreadContext,
>>> org.jruby.runtime.builtin.IRubyObject);
>>> descriptor:
>>> (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/RubyBoolean;
>>>
>>> ...
>>> RuntimeVisibleAnnotations:
>>> 0: #123(#124=[s#149],#150=I#137)
>>>
>>> And here's the bridge method, which also acquires this annotation:
>>>
>>> public org.jruby.runtime.builtin.IRubyObject
>>> op_equal(org.jruby.runtime.ThreadContext,
>>> org.jruby.runtime.builtin.IRubyObject);
>>> descriptor:
>>> (Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject;
>>>
>>> flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
>>> ...
>>> RuntimeVisibleAnnotations:
>>> 0: #123(#124=[s#149],#150=I#137)
>>>
>>> I'm not arguing that this is correct or incorrect behavior...merely
>>> that it is a change, and it may bite others the same way it has bitten
>>> us. I have patched our stub generator to skip bridge methods, but it
>>> feels kinda wrong.
>>
>> This is not a bug but intended behavior, I implemented this as a
>> feature request, see [1]. Some users asked this as a nice to have
>> feature :)
>>
>> [1] https://bugs.openjdk.java.net/browse/JDK-6695379
>
> while I agree that it's a feature not a bug, or even a bugfix if you
> consider that without that fix you have a way to bypass
> JavaEE security frameworks that use annotations.
> Anyway, it has to be documented in the compatibility notes because
> this change in the behavior
> may impact some annotations processor or runtime that use the
> annotations.
Thanks for your suggestion, I have modified the bug entry accordingly.
Vicente
>
>>
>>>
>>> - Charlie
>>
>
> Rémi
>
More information about the compiler-dev
mailing list