Version: 5.3.25 (via Boot 2.7.17)

I have an @Configuration class defining an @Bean method:

@Bean
@MyQualifier
ServiceObject serviceObject() {
  new ServiceObject()
}

When @MyQualifier is annotated with @javax.inject.Qualifier, the Spring container does not treat it as a qualifier, resulting in duplicate-bean exceptions. Adding Spring's org.springframework.beans.factory.annotation.Qualifier to the annotation type fixes the injection problem.

I have traced the problem as far as AbstractBeanFactory#getMergedLocalBeanDefinition(String), where the this.mergedBeanDefinitions returns an mbd that does not copy the @javax.inject.Qualifier-annotated annotation (mbd.qualifiers is empty). I am trying to figure out where the RootBeanDefinition gets constructed and should have the qualifier recorded but doesn't.

Update: It appears the problem may be that the upstream library declares jakarta.inject-api as an optional dependency, so that the Spring container's check on whether javax.inject.Qualifier is present on the classpath does not see it unless the consuming project independently requires the library (even though the intermediate @MyQualifier is visible with no problems).

If this is the case, it would be convenient if possible to provide a warning if a meta-annotated annotation is found but the intermediate javax.inject.Qualifier isn't, but in contrast to Boot's bytecode inspection I believe the core Spring container relies on plain JVM reflection and wouldn't have visibility on it.

Comment From: snicoll

If the Qualifier annotation isn't available, @MyQualifier isn't even considered. It's just one annotation like any other annotation so there's no way for the container to see it has to issue a warning.