Skip to content

Deprecate AnnotationFilter.NONE (since MergedAnnotations always filters java.lang.* annotations) #24932

Closed
@neiser

Description

@neiser

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!

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: documentationA documentation task

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions