spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.23k stars 37.98k forks source link

No qualifying bean of type 'java.lang.String' in case of accidental `@Autowired` `@Bean` method with `@Value` parameter #33030

Closed jimshowalter closed 3 months ago

jimshowalter commented 3 months ago

A few minutes ago ./gradlew dependencyUpdates showed that 6.1.9 is available.

Upgraded to that from 6.1.8, and startup failed like this:

2024-06-14 07:13:50,853 DEBUG [main] DefaultListableBeanFactory: Creating shared instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2024-06-14 07:13:50,854 DEBUG [main] DefaultListableBeanFactory: Creating shared instance of singleton bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration'
2024-06-14 07:13:50,855 DEBUG [main] DefaultListableBeanFactory: Bean creation exception on singleton FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' available
2024-06-14 07:13:50,856 DEBUG [main] LoggingFailureAnalysisReporter: Application failed to start due to an exception
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1880)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1406)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:887)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:848)
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:145)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:508)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1421)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:409)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1337)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1167)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:365)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:135)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1687)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1436)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:904)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:782)
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1357)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1194)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:904)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:782)
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1357)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1194)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:904)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:782)
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1357)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1194)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:904)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:782)
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1357)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1194)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:962)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352)
        at com.foo.ServiceApplication.main(ServiceApplication.java:30)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91)
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53)
        at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:58)
2024-06-14 07:13:50,863 ERROR [main] LoggingFailureAnalysisReporter: 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method fooClient in com.foo.Bar$$SpringCGLIB$$0 required a bean of type 'java.lang.String' that could not be found.

Action:

Consider defining a bean of type 'java.lang.String' in your configuration.

Should be a really easy regression to track down, between those two minor versions.

jhoeller commented 3 months ago

What does the fooClient method signature look like? Apparently it has a parameter of type String which the container tries to resolve as a bean, maybe due to a missing indication that it is rather meant to be some other kind of value?

jhoeller commented 3 months ago

On review, that exception stacktrace is a bit confusing. It actually seems to be an @Autowired method that fails to inject that String, not a @Bean factory method as I originally assumed. In any case, it is unclear what it is trying to obtain there.

jimshowalter commented 3 months ago

All we know is that we changed nothing except the one version, and this broke. What went into 6.1.9 that could have caused this regression?

snicoll commented 3 months ago

@jimshowalter can you reproduce on several machines? This looks really low-level and nothing that rings a bell. Perhaps a JAR is corrupted?

jimshowalter commented 3 months ago

A jar is not corrupted. We trivially upgraded Spring as part of our normal housekeeping, and it blew up our service, which has worked without any Spring-related issues for literally years.

jimshowalter commented 3 months ago

Tried another of our services, exact same failure.

snicoll commented 3 months ago

A jar is not corrupted.

How do you know that?

Can you reproduce on several machines is my question. We're both trying to help you and your replies are not helpful. Please take the time to process the feedback as it's unclear what your setup is. If this is so easy to reproduce, you should be able to provide us a sample. Also, the above is using Spring Boot so it's unclear why you didn't upgrade that rather than framework explicitly.

jimshowalter commented 3 months ago

This is on several machines. It fails locally on a Mac M1, and in our Jenkins pipeline on RHEL8.

jimshowalter commented 3 months ago

It's definitively straightforward to reproduce in our services, but asking us to cut it down to a small reproducible test case is not so straightforward.

We're assuming this will prove to be a systemic problem with the latest 6.1.9, and that others will start reporting the same error.

bclozel commented 3 months ago

The entire Spring Boot test suite has upgraded to Spring Framework 6.1.9 and ran successfully, exercising quite a lot of integration tests in the process. We're not asking for a test case, but rather a simple application created on https://start.spring.io that fails. Given your feedback, this should be pretty straigthforward to replicate the bean/injection arrangement and demonstrate the failure.

jhoeller commented 3 months ago

There's always a chance for regressions but I'm afraid this is not a very obvious one. We will need your help to reproduce this in some way.

Oh, and thanks for trying 6.1.9 early. Anything to fix here, we can still do so for the corresponding Spring Boot releases next Thursday.

jimshowalter commented 3 months ago

2024-06-14 08:18:46,306 DEBUG [main] DefaultListableBeanFactory: Creating shared instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' 2024-06-14 08:18:46,306 DEBUG [main] DefaultListableBeanFactory: Creating shared instance of singleton bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' 2024-06-14 08:18:46,307 DEBUG [main] DefaultListableBeanFactory: Bean creation exception on singleton FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' available 2024-06-14 08:18:46,308 DEBUG [main] LoggingFailureAnalysisReporter: Application failed to start due to an exception org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

jimshowalter commented 3 months ago

The problem with trying to create a test case is, you already had a bunch of test cases that didn't catch this, and in the past whenever we've tried to reduce a large git repo to a small test case, the problem went away.

You're asking us to basically spend a couple of days trying to boil this down to something small, when the problem could be due to interactions among many components, none of which are under our control.

./gradlew dependencyUpdates (the ben-manes dependencies plugin) shows that all of our dependencies are on the latest versions, if that helps at all.

jhoeller commented 3 months ago

If you see the same failure in several services, do you mean the very same fooClient signature leading to a String resolution exception? Do you happen to have common dependencies among your services that include this fooClient method signature?

Since I imagine this has been masked with the foo/bar naming there, it would be good to identify what kind of method it is that actually fails there. Otherwise, we have no chance to get closer to the problem.

jimshowalter commented 3 months ago

./gradlew dependencyUpdates

Task :dependencyUpdates


: Project Dependency Updates (report to plain text file)

The following dependencies are using the latest milestone version:

Gradle release-candidate updates:

Generated report file build/dependencyUpdates/report.txt

snicoll commented 3 months ago

This isn't going anywhere. If you don't want to take the time to provide the info, we unfortunately won't be able to help until someone else does (assuming they're affected by the same issue). I am not sure the exception you've shared is the root cause but rather a cascading effect of something else. You could share the full starting log of your application (by email if you don't want to provide them here) as well as the code that contributed com.foo.Bar$$SpringCGLIB$$0 (the fooClient).

jimshowalter commented 3 months ago

Email to where?

jimshowalter commented 3 months ago

The exception I provided is the first one in the logs. That's something every user of Spring learns early--later exceptions are noise.

jhoeller commented 3 months ago

As for the dependencies, since you have aspectjweaver there: Any use of custom @Aspect classes? We did have some recent revisions there fixing other regressions (e.g. #32882, #32970) - maybe this has a side effect in your scenario. Although the real problems were in 6.1.7 there, 6.1.8 and 6.1.9 are just wrapping it up.

snicoll commented 3 months ago

The exception I provided is the first one in the logs.

I've never said the opposite. But you sharing 4 log entries and letting us guess what could go wrong isn't going to work. Your attitude isn't helpful (and quite frankly obnoxious IMO). We can reset perhaps and you can appreciate we're trying to help you? If you won't share details here, please email them at <firstname.lastname@broadcom.com>

jimshowalter commented 3 months ago

Jeez, I thought you'd appreciate knowing about the problem. Not sure what you mean by attitude, and it's pretty obnoxious to call me obnoxious, IMHO. I tried to provide the relevant information, probably cannot boil it down into a small test case based on previous attempts for other bug reports (that were later substantiated by other users reporting in). Anyway, either this is unique to us, and we'll just have to never upgrade, or others will start trying to use the latest and run into this same problem, find it online, and chime in.

I emailed the full startup log to that email address. As I said though, it doesn't contain any more information than I'd already posted. There's only the one exception.

jimshowalter commented 3 months ago

Well, tried to mail it anyway:

The response was: The email account that you tried to reach does not exist. Please try double-checking the recipient's email address for typos or unnecessary spaces. For more information, go to https://support.google.com/mail/?p=NoSuchUser [support.google.com]

snicoll commented 3 months ago

Did you replace firstname and lastname with stephane and nicoll respectively?

jimshowalter commented 3 months ago

Doh. Thought you meant my name. Sent.

jhoeller commented 3 months ago

Since it might have been lost in the stream of comments above: please see https://github.com/spring-projects/spring-framework/issues/33030#issuecomment-2168312766 - do you have any custom use of AspectJ in your setup? The stacktrace does not indicate so, just checking since there have been some recent regressions and regression fixes in that area.

jimshowalter commented 3 months ago

I'm trying to create a cut-down test case. We have some custom aspects. Will try to cut it down enough to be able to see if those are causing it.

jhoeller commented 3 months ago

For a bit of context from our side: The key problem in our recent AspectJ support revision is Spring AOP with AspectJ aspect classes versus compile-time and load-time weaving. We have to accept ajc-compiled aspects for use with Spring AOP now, according to recent AspectJ recommendations for reusable aspect classes, whereas traditionally such ajc-compiled aspects were exclusively encountered with bytecode weaving.

Looking at your provided log, I see no "Ignoring incompatible aspect/advice" entries, so it does not seem to be those two new defensive catch blocks for AspectJ processing that we added in 6.1.9. The only other change in 6.1.9 is that we avoid potential duplicate execution of aspects through not applying ajc-compiled aspect classes to ajc-compiled bean classes in the application, assuming that those have been compile-time or load-time weaved.

In any case, we intend to keep existing setups running as far as possible. If some variation of the above turns out to be the root of the problem here, we're keen to fix it in time for the Spring Boot releases next Thursday.

jimshowalter commented 3 months ago

Managed to boil it down into a simple test case. It's having trouble taking config values from yaml and passing them into a configuration object. See README.md.

foo.zip

jimshowalter commented 3 months ago

@snicoll @jhoeller

jhoeller commented 3 months ago

Thanks @jimshowalter, we'll sort it out ASAP. Getting late here in European time, might take until Monday to get fully into it.

From a quick glance: That blowsUp method should not declare @Bean as well as @Autowired. Looks like it is primarily a factory method, so @Bean alone should be sufficient, with the constructor arguments naturally getting autowired then. With an extra @Autowired there, the container tries to call that method separately as a setter-like method, failing in your stacktrace.

Such a plain @Bean declaration should work fine on any Spring version, so I strongly recommend that in any case. If this still fails for you, we need to see why @Value is apparently not detected, with the container thinking it needs to autowire a plain String instead. If this works with just @Bean, we need to see why we tolerated a superfluous @Autowired there before but not after.

jimshowalter commented 3 months ago

Interesting--that indeed fixed it!

We'll make a pass through our services looking for more examples of unnecessary annotations.

jhoeller commented 3 months ago

Glad to hear! We'll try to find out why we tolerated that before then.

Even with the extra annotation, it should still start up properly (even when calling that method twice for separate purposes), so we'll try to restore the previous behavior there in any case... maybe with a warn log entry though, otherwise such an accidental overuse of @Autowired is hard to notice.

jhoeller commented 3 months ago

This turns out to be a side effect caused by #32888 where bridge method resolution is more capable now. Previously, we did not detect @Autowired on CGLIB-processed @Bean methods, now we do on the original class... but we still use the CGLIB-overridden method (which does not include any annotations) for parameter resolution which fails for @Value.

So we accidentally ignored such an arrangement before, now - for a different accident - we process it and expose a side effect of the mismatch. The correct solution is to never declare @Autowired next to @Bean on the same method... but since we did effectively tolerate it before, we need to make sure we tolerate it again in 6.1.10 in some form.

jimshowalter commented 3 months ago

Or release a breaking change? It's not difficult to fix the breakages.

jhoeller commented 3 months ago

We might actually do a breaking change in a future release, forcing such accidental declarations to be cleaned up.

It's just the potential mid-line breakage in 6.1.x - possibly on code that the people affected cannot easily change since it is not in their hands - that we need to find a remedy for. That is totally doable, just a matter of where specifically (BridgeMethodResolver or AutowiredAnnotationBeanPostProcessor).

quaff commented 3 months ago

Another workaround is setting proxyBeanMethods of @Configuration to false if you are not using "inter-bean references".

denAbramoff commented 3 months ago

Hi! I got other example this exception with using

 @Bean
 public ArrayList<> .... 

No qualifying bean of type 'java.util.List<?>' available: expected single matching bean but found ...

And, yes, it stems from @Configuration. After proxyBeanMethods = false this exception was gone.

snicoll commented 3 months ago

@quaff thanks for trying to help but there's no workaround needed if you can modify the @Configuration class to remove the unnecessary @Autowired.

@denAbramoff can you please move that to a new issue with more details? When you do please add more content than just those two lines as we won't be able to make much of that.

denAbramoff commented 3 months ago

We used @Autowired and @Beantogether ... i left only @Bean and the exception again was gone.