Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DependencyDescriptor#getDependencyName() returns null in 6.1.2, but not 6.0.x or earlier #31998

Closed
fatso83 opened this issue Jan 10, 2024 · 4 comments
Labels
status: invalid An issue that we don't feel is valid

Comments

@fatso83
Copy link

fatso83 commented Jan 10, 2024

Affects: 6.1.2

It is not present in spring-framework version 6.0.15 (shipped with Spring Boot 3.1.7)

When upgrading from any Spring Boot 3.1 version (tried 3.1.2 and 3.1.7) of Spring Boot to Spring Boot 3.2 (both 3.2.0 and 3.2.1 tried) our tests break with issues such as expected single matching bean but found 2: clientAdminDataSource,dataSource or expected single matching bean but found 2: clientAdminTemplateJdbcTemplate, jdbcTemplate. This has worked through all Spring Boot versions up until 3.2.0

I then went and tried to reproduce the issue, thinking the issue was that autowiring in 3.2.0 somehow was not excluding the @Configuration bean that was set to be excluded in our @TestConfiguration bean, thus ending up with multiple candidate beans. The reproduction (at fatso83/issue-reproductions/spring-3.2.0-autowire-issue) failed to display the issue, which forced me to do some more debugging, comparing test runs in 3.1 and 3.2. It turns out

  1. exclusion seems to work fine in 3.2
  2. there were multiple candidate beans in the 3.1 tests as well, but the autowire code managed to figure out which was the right one (based on the heuristics of name matching, etc)

My attempt at reproducing was unsuccessful, so my only clues must be in what is different.

The main difference I can see is that in our production setup, the beans that fails to map up are either DataSource's or JdbcTemplates. So type/class seems to matter somehow. Both of these types have @Bean's supplied by Spring itself (the default ones). This is of course not the case for my Foo and Bar classes in the repro.

Where the bug manifests in Spring: DefaultListableBeanFactory#determineAutowireCandidate().

When DefaultListableBeanFactory#doResolveDependency() calls that method the code looks like this:

// Step 4: determine single candidate
if (matchingBeans.size() > 1) {
    autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
    if (autowiredBeanName == null) {

In Spring 3.1.7 (and 3.1.2), autowiredBeanName returns one bean. In Spring 3.2.0 and 3.2.1, it returns null. The reason is this code:

			if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
					matchesBeanName(candidateName, descriptor.getDependencyName())) {
				return candidateName;
			}

descriptor.getDependencyName() returns null in 3.2, but not 3.1, so naturally this fails.

It was at this point I got dizzy trying to debug this, diving further into a rabbit hole I had no idea where was going, so
that's when I gave up and just submitted the bug without knowing what goes wrong.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 10, 2024
fatso83 added a commit to fatso83/issue-reproductions that referenced this issue Jan 10, 2024
@jhoeller
Copy link
Contributor

This looks like you are missing the -parameters compiler flag. This issued warnings before, as of 6.1 we do not parse debug symbols anymore but rather rely on Java 8 parameters support.

See the note in https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x

@snicoll snicoll added the status: waiting-for-feedback We need additional information before we can continue label Jan 10, 2024
@fatso83
Copy link
Author

fatso83 commented Jan 10, 2024

Indeed it was! The description in Parameter Name Retention for 6.1 was spot on. No idea why this wasn't an issue in the reproduction, but I won't bore you with that. Thanks!

Hopefully all the details should guide some other unlucky soul to the solution 😄 No amount of googling, reading/searching for Github issues in Spring and reading of Changelogs (the wrong ones, it turns out) helped us find the issue, so leaving a trace.

P.S. We did read the release docs, but I cannot see this mentioned. Tried searching for "reflection" and could not see a direct hit. Maybe worth adding.
Found it mentioned in the 6.1.0-M1 pre-release from June. Was done as #29559

@fatso83 fatso83 closed this as completed Jan 10, 2024
@bclozel
Copy link
Member

bclozel commented Jan 10, 2024

This was not a problem with the repro project because Spring Boot configures the parameters flag by default with the maven compiler plugin.

@bclozel bclozel closed this as not planned Won't fix, can't repro, duplicate, stale Jan 10, 2024
@bclozel bclozel added status: invalid An issue that we don't feel is valid and removed status: waiting-for-feedback We need additional information before we can continue status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 10, 2024
@fatso83
Copy link
Author

fatso83 commented Jan 10, 2024

This was not a problem with the repro project because Spring Boot configures the parameters flag by default with the maven compiler plugin.

Not quite. That wasn't the case, as I was duplicating the configuration of the production setup having issues, where the beans in question were set up (and compiled) in a dependency that had nothing to do with Spring Boot (it just depended on Spring).

The real issue with the repro was that while I did create multiple beans, I never had the issue where there were multiple candidates for parameter injection, only field injection, so it did not exercise the same code. Once I knew that the issue was really about matching on parameter name, I simplified the whole repro into just having the code to show the issue.

Thanks anyhow! We struggled quite a bit with this 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

5 participants