Closed jimshowalter closed 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?
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.
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?
@jimshowalter can you reproduce on several machines? This looks really low-level and nothing that rings a bell. Perhaps a JAR is corrupted?
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.
Tried another of our services, exact same failure.
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.
This is on several machines. It fails locally on a Mac M1, and in our Jenkins pipeline on RHEL8.
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.
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.
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.
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: {}
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.
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.
./gradlew dependencyUpdates
Task :dependencyUpdates
The following dependencies are using the latest milestone version:
Gradle release-candidate updates:
Generated report file build/dependencyUpdates/report.txt
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
).
Email to where?
The exception I provided is the first one in the logs. That's something every user of Spring learns early--later exceptions are noise.
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.
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>
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.
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]
Did you replace firstname and lastname with stephane and nicoll respectively?
Doh. Thought you meant my name. Sent.
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.
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.
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.
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.
@snicoll @jhoeller
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.
Interesting--that indeed fixed it!
We'll make a pass through our services looking for more examples of unnecessary annotations.
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.
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.
Or release a breaking change? It's not difficult to fix the breakages.
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
).
Another workaround is setting proxyBeanMethods
of @Configuration
to false if you are not using "inter-bean references".
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.
@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.
We used @Autowired
and @Bean
together ... i left only @Bean
and the exception again was gone.
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:
Should be a really easy regression to track down, between those two minor versions.