Inverse annotation inheritance issue with generic interfaces

Alex Buckley alex.buckley at oracle.com
Mon Nov 23 20:41:26 UTC 2015


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.

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