Suppose the following:
@SomeAnnotation
public interface Foo {
}
I would like to know if it is always the case that either the defining classloader of SomeAnnotation
is equal to or a parent of the initiating classloader of Foo
.
I have read JVMS v8 section 5.3. but I'm not sure what applies here. Section 5.3.4 talks about loading constraints, but they seem not to apply for annotations.
The question I'm asking is because code like this:
Class<?> fooClass = //will in some way obtain a reference to class Foo
fooClass.getAnnotation(SomeAnnotation.class);
will fail in the presence of different classloaders. I know I could use getAnnotations and search in the resulting array for an element whose class name is equal to the name of SomeAnnotation
. But I'm wondering if the following will work too:
Class<?> fooClass = //will in some way obtain a reference to class Foo
fooClass.getAnnotation((Class<? extends Annotation>) fooClass
.getClassLoader().loadClass(SomeAnnotation.class.getName()));
The short answer: no
The long answer.
RetentionPolicy.RUNTIME
annotations are available for discovery via the reflection API only. This is done to ensure loose coupling between annotations and annotated code. According to this bug report, getAnnotations()
must skip unknown annotations which implies that it's ok to have annotations that are not recognized by the classloader. The behavior of real Java code discussed here validates that assumption.
This behavior has two implications:
For example if somepkg.SomeAnnotation
was not in classpath when someClass
was loaded, this will not work:
Class<?> someClass = ....
URL [] classPathWithAnnotations = ....
ClassLoader cl = new URLClassLoader(classPathWithAnnotations);
Annotation a = someClass.getAnnotation(cl.loadClass("somepkg.SomeAnnotation"));
// a will be null
But this will:
Class<?> someClass = ....
URL [] classPathWithSomeClassAndAnnotations = ....
ClassLoader cl = new URLClassLoader(classPathWithSomeClassAndAnnotations, null);
Annotation a = cl.loadClass(someClass.getName()).getAnnotation(cl.loadClass("somepkg.SomeAnnotation"));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With