Qualifiers aren't captured by AOT in the generated BeanDefinitions classes, leading to failures when running under AOT:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.example.demo.DemoApplication$RequiresGrpcClient required a bean of type 'com.example.demo.DemoApplication$GrpClient' that could not be found.
The injection point has the following annotations:
- @com.example.demo.GrpcSpringClient("myclient")
The following candidates were found but could not be injected:
- User-defined bean
Action:
Consider revisiting the entries above or defining a bean of type 'com.example.demo.DemoApplication$GrpClient' in your configuration.
In our specific case, they're custom qualifier annotations and definitions registered by a registry post-processor. It appears for simple annotated Qualifier beans, the framework is able to fallback and infer the qualifier.
Example project:
https://github.com/DanielThomas/spring-aot-issues/tree/dannyt/qualifier-missing
Run and note the failure:
./gradlew bootJar && java -Dspring.aot.enabled=true -jar build/libs/demo-0.0.1-SNAPSHOT.jar
Comment From: sdeleuze
To be checked if #29709 is related or not.
Comment From: snicoll
In our specific case, they're custom qualifier annotations and definitions registered by a registry post-processor.
Static qualifiers are supported as you've found out. We haven't had a use case of something like this being set programmatically. Thanks for the reproducer!
Comment From: snicoll
It looks like we should support a form of AutowireCandidateQualifier where any value we can handle with AOT is actually written in code. I don't know if we can short-circuit the algorithm that checks for the @Qualifier annotation, but it's worth a try.
Comment From: snicoll
I think I have a fix for this with https://github.com/snicoll/spring-framework/commit/2f41ce6449c60b5a22b87b6a33784c6035499212. Building your reproducer with it adds the following line to the bean definition.
beanDefinition.addQualifier(new AutowireCandidateQualifier("com.example.demo.GrpcSpringClient", "myclient"));
I'd like to spend a bit more time on what we do for @Qualifier and the impact processing those may have. But I am hopeful to get a fix for 6.0.9.