Skip to content

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

Closed as not planned
@fatso83

Description

@fatso83

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: invalidAn issue that we don't feel is valid

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions