Affects: 5.3.3


Injecting by qualifier doesn't work when target collection is declared as List<? extends Object>, which is how Kotlin translates List<Any>.

Reproducer:

package example;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.util.List;

@Configuration
@ComponentScan
public class ExampleApplication {
    public static void main(String[] args) {
        new AnnotationConfigApplicationContext(ExampleApplication.class);
    }
}

@Component
@Qualifier("EXAMPLE")
class Foo {}

@Component
class Bar {
    public Bar(
        @Qualifier("EXAMPLE") List<Object> good,
        @Qualifier("EXAMPLE") List<? extends Object> bad
    ) {
        System.out.println("Good " + good);
        System.out.println("Bad: " + bad);
    }
}

Output:

Good [example.Foo@5552768b]
Bad: []

Comment From: ooooo-youwillsee

This doesn't seem like Spring's bug, I find a simple Java Demo

class Bar {

    public Bar(
            @Qualifier("EXAMPLE") List<? extends Foo> p1,
            @Qualifier("EXAMPLE") List<? extends Object> p2,
            @Qualifier("EXAMPLE") List<?> p3
    ) {
        System.out.println("p1: " + p1);
        System.out.println("p2: " + p2);
        System.out.println("p3: " + p3);
    }

    public static void main(String[] args) {
        Constructor<?> constructor = Bar.class.getConstructors()[0];
        Type[] genericParameterTypes = constructor.getGenericParameterTypes();
        for (Type parameterType : genericParameterTypes) {
            if (parameterType instanceof ParameterizedType) {
                System.out.println(parameterType);
            }
        }
    }

}

output

java.util.List<? extends com.ooooo.Foo>
java.util.List<?>
java.util.List<?>

In fact, ? extend Object seem to equals ?.

I found an interesting part Collection.class.isAssignableFrom(type) && type.isInterface() for resolve collection in org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveMultipleBeans method, ? as ResolvableType will return null in spring.

Comment From: hban

I apologize if pinging is frowned upon here, but could someone take a look at this issue? It has been waiting for triage for several months now.

If it might help, there was a somewhat similar issue I opened for Spring Boot before (spring-projects/spring-boot#18767), which was fixed. Maybe the cause is same as for this issue?

Comment From: sbrannen

Superseded by #24145