Description
The following test case
@Test
void deprecatedAnnotationShouldBeFoundIfFilterIsNone() {
List<MergedAnnotation<Deprecated>> deprecatedAnnotations = MergedAnnotations.from(
TestClass.class,
MergedAnnotations.SearchStrategy.DIRECT,
RepeatableContainers.standardRepeatables(),
AnnotationFilter.NONE // That should include java.lang.* annotations?!
).stream(Deprecated.class).collect(Collectors.toList());
assertThat(deprecatedAnnotations).hasSize(1); // fails!
}
@java.lang.Deprecated
private static class TestClass {
// just for testing
}
fails although I've specified AnnotationFilter.NONE
instead of the default AnnotationFilter.PLAIN
filter option. I'd expect the annotation to be found (and thus the I expect the list to contain one element instead of being empty).
I suspect this is a bug since as a user of the MergedAnnotations API I expect that the AnnotationFilter.NONE
returns all possible annotations, even if they're part of java.lang
package.
I think I tracked the problem down to the following method
org.springframework.core.annotation.AnnotationsScanner#isIgnorable
:
private static boolean isIgnorable(Class<?> annotationType) {
return AnnotationFilter.PLAIN.matches(annotationType);
}
which is used when getting the list of annotations from the annotated element in org.springframework.core.annotation.AnnotationsScanner#getDeclaredAnnotations(java.lang.reflect.AnnotatedElement, boolean)
. However, I'm no expert for this part of the framework and I might be that I'm mistaken if that's the origin of the bug.
I don't know how to propose a fix for this and why this isIgnorable
method is used, but I hope you agreed that this is a bug or at least unexpected behavior for using the filter option NONE
.
Also note that this bug is usually hidden by a shortcut in for example org.springframework.core.annotation.AnnotationUtils#findAnnotation
:
// Shortcut: directly present on the element, with no merging needed?
if (AnnotationFilter.PLAIN.matches(annotationType) ||
AnnotationsScanner.hasPlainJavaAnnotationsOnly(annotatedElement)) {
return annotatedElement.getDeclaredAnnotation(annotationType);
}
So either the comment is not correct that this is just a shortcut but actually also finding annotations matching PLAIN
, or the MergedAnnotations API has a bug, as explained above.
Background: I'm working on a Spring-based library and would like to find a bunch of annotations, some of them mergable, but some not. I wouldn't like to use different search utilities and always use the MergedAnnotations API, no matter what kind of annotation I'm looking for within my library.
Thanks a lot for investigating!