Inverse annotation inheritance issue with generic interfaces
Lukas Magel
luke-mail at online.de
Mon Nov 23 13:35:33 UTC 2015
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