Inverse annotation inheritance issue with generic interfaces
Lukas Magel
luke-mail at online.de
Thu Nov 26 14:30:12 UTC 2015
Thanks for your help! Since the behavior is intended the issue seems to
be a problem with the Jax-RS implementation. I guess I will bring this
up again on their mailing list. Maybe they can work out a fix on their end.
Lukas
On 24.11.2015 01:09, Alex Buckley wrote:
> On 11/23/2015 1:50 PM, Maurizio Cimadamore wrote:
>> On 23/11/15 20:41, Alex Buckley wrote:
>>> Enumerating the methods of Main.class shouldn't reveal
>>> sampleMethod(A), since sampleMethod(B) overrides it. I suspect a
>>> bridge method bug is being tickled, probably in Core Reflection rather
>>> than javac.
>> Not sure what you mean here - as far as I recall, reflection always
>> listed all methods (bridges included) in a given class.
>
> Hard to confirm from the javadoc (as usual), but I imagine you're right.
>
>> I think what is being observed is this:
>>
>> https://bugs.openjdk.java.net/browse/JDK-669537
>>
>> Which I think was a legitimate fix - the callee probably wants to be
>> able to retrieve all applicable annotations, regardless of whether it
>> accidentally hit the bridge doing the reflective lookup.
>
> I guess the fix was to emit the RuntimeVisibleAnnotations attribute
> for the bridge method sampleMethod(A) -- the change from non-emission
> (in 1.7.0_51) to emission (in 1.7.0_85) is visible in Lukas' javap
> output.
>
> Ah, and here's the thread from exactly two years ago:
>
> Annotations on return-overridden methods also end up on bridge methods
>
> http://mail.openjdk.java.net/pipermail/compiler-dev/2013-November/008147.html
>
>
> So Lukas, the behavior is intended. See
> https://bugs.openjdk.java.net/browse/JDK-6695379 for more.
>
> Alex
>
>> Maurizio
>>> What is the full javap output for Main.class as compiled with Oracle
>>> JDK 1.7.0_51 versus Oracle JDK 1.7.0_85 ? (Plain text inline, please.)
>>>
>>> Alex
>>>
>>> On 11/23/2015 5:35 AM, Lukas Magel wrote:
>>>> Hello,
>>>>
>>>> I am currently working on a Java EE web project and have been
>>>> experiencing a compiler behavior which I don't know how to interpret.
>>>>
>>>> In our code we define interfaces like the following:
>>>>
>>>> public interface SampleInterface<T extends A> {
>>>>
>>>> public void sampleMethod(T t);
>>>>
>>>> }
>>>>
>>>> as well as an implementing class:
>>>>
>>>> public class Main implements SampleInterface<B> {
>>>>
>>>> @SampleAnnotation
>>>> public void sampleMethod(B t) {
>>>>
>>>> }
>>>> }
>>>>
>>>> and the corresponding annotation:
>>>>
>>>> @Retention(RetentionPolicy.RUNTIME)
>>>> @Target(ElementType.METHOD)
>>>> public @interface SampleAnnotation {
>>>>
>>>> }
>>>>
>>>> Where Class B extends A. All classes are compiled using the OpenJDK
>>>> compiler. If I use Reflection to retrieve all methods of the Main
>>>> class
>>>> at runtime and print each method with its annotations I get the
>>>> following list of methods:
>>>>
>>>> class Main
>>>>
>>>> public void Main.sampleMethod(A)
>>>> @SampleAnnotation()
>>>>
>>>> public void Main.sampleMethod(B)
>>>> @SampleAnnotation()
>>>>
>>>> The compiler will assign the annotation to the method declaration
>>>> of the
>>>> interface although the annotation is only declared in the implementing
>>>> class. I cannot reproduce this behavior with the Oracle Java
>>>> Compiler or
>>>> the Eclipse JDT Compiler. If I compile the example with one of the two
>>>> compilers the resulting program will yield the following result:
>>>>
>>>> class annotation.Main
>>>>
>>>> public void Main.sampleMethod(A)
>>>>
>>>> public void Main.sampleMethod(B)
>>>> @SampleAnnotation()
>>>>
>>>> The JRE type (Oracle, OpenJDK) that the program is executed with
>>>> has no
>>>> influence on the result.
>>>>
>>>> This behavior is reproducible with the following constellations:
>>>> JDK Operating System Hardware
>>>> 1.7.0_85 Ubuntu 14.04.03 x86-64
>>>> 1.7.0_91 Arch Linux x86-64
>>>> 1.8.0_66 Arch Linux x86-64
>>>>
>>>> It is NOT reproducible with the following constellation:
>>>> 1.7.0_51 Ubuntu 13.04 x86-64
>>>>
>>>> My actual question is whether this behavior is intended or not. It
>>>> causes quite some issues with our Jax-RS REST implementations. All
>>>> REST
>>>> classes each implement an interface like the one above and are
>>>> annotated
>>>> with multiple annotations to allow the container to identify endpoints
>>>> at runtime. The Jax-RS framework uses reflection to determine possible
>>>> method candidates at runtime and will happily accept both the generic
>>>> and the special method since both of them carry the annotations.
>>>>
>>>> I can also provide an example project if necessary.
>>>>
>>>> Thanks,
>>>> Lukas
>>
More information about the compiler-dev
mailing list