Since Spring Boot 2.2.0 the excludeFilters of @ComponentScan is ignored when loading the Spring Boot application context.
When using a configuration class, loaded with spring.factories which does a @ComponentScan for the "framework" it provides, the application context is loading configuration classes which should be excluded (added to the excludeFilters). In version 2.1.11 all works fine. Starting from 2.2.0 the excluded class is loaded causing the context to fail.
I added a small maven project to reproduce the issue. Switch parent pom version to 2.2.0 (or later) and maven build will fail. It looks like a Spring Boot (test context?) issue. Tests using a standard Spring context are not affected (common-framework-boot-supportmodule), the @SpringBootTest tests are (application module).
spring-componentscan-issue.zip
Comment From: snicoll
Thanks for the sample. Debugging shows me that the exclude filter is read and added to the scanner but scan includes the class anyway. Moving to spring-framework for further inspection as I don't see how it could be related to Spring Boot.
Comment From: rob-valor
Indeed, sometimes the most basic things tend to be skipped when facing/solving a software issue 😊 . ~~Yes, also@SpringBootApplication also does a classic @ComponentScan. I modified the example to (1) not fail the context having a cleaner test failure instead of blowing up and (2) build a classic spring context by also adding a @ComponentScan to the common-framework-boot-support module which, without having Spring Boot on the classpath, also fails to properly apply the excludeFilters.
spring-componentscan-issue_update.zip~~
It's just the exclude filter that is not applied with nothing special involved affecting the behavior of the component scanning. simple-example.zip has a simple context with 1 class to scan and 1 class to exclude. Failing test starting from Spring 5.2
Comment From: rob-valor
The issue seems to be in AnnotationTypeFilter#matchSelf. The AnnotationMetadata implematation is completely different (5.2: SimpleAnnotationMetadata, 5.1: AnnotationMetadataReadingVisitor) and apparently missing valuable class level annotation information. AnnotationMetadata#hasAnnotation returns false when looking for my excludeFilters marker annotation which it does not in Spring 5.1.
Hope this helps.
Comment From: snicoll
@rob-valor great detective work! I suspected indeed the new annotation API retrieval to have a regression in this area. Thanks for the updated sample.
Comment From: sbrannen
The solution is to ensure that your annotation is properly retained at runtime.
If you declare @DoNotScan as follows, your test passes as expected.
@Retention(RetentionPolicy.RUNTIME)
public @interface DoNotScan {
}
This is effectively a duplicate of #23901.
See https://github.com/spring-projects/spring-framework/issues/23901#issuecomment-549144453 for details, specifically:
As of Spring Framework 5.2, all annotations are now required to be annotated with
@Retention(RetentionPolicy.RUNTIME)in order for Spring to see them.
I am therefore closing this issue.
Comment From: rob-valor
We'll update our code then. Thanks. Apparently I didn't read the complete part of core container in Upgrading to Version 5.2. Sorry guys :wink:
Comment From: plum117
Thanks I had the same issues, adding @Retention(RetentionPolicy.RUNTIME) solved it!