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