Skip to content

Autowiring unable to find generic dependency in case of nested unresolved type variable [SPR-11471] #16096

Closed
@spring-projects-issues

Description

@spring-projects-issues

Jair da Silva Ferreira Júnior opened SPR-11471 and commented

Hi,
I believe I found an issue with autowiring and generics.
I attached a simple eclipse example project to show you the issue.

Here is my "application-context.xml" file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.2.xsd">

	<context:annotation-config/>
	
	<bean class="spring.test.generics.GenericInterface1Impl" factory-method="create"/>
	<bean class="spring.test.generics.GenericInterface2Impl"/>
</beans>

I have 2 classes: "GenericInterface1Impl" and "GenericInterface2Impl".
"GenericInterface1Impl" depends on an implementation of "GenericInterface2".

public class GenericInterface1Impl<T> implements GenericInterface1<T>{

	@Autowired
	private GenericInterface2<T> gi2;

	@Override
	public String doSomethingGeneric(T o) {
		return gi2.doSomethingMoreGeneric(o) + "_somethingGeneric_" + o;
	}
	
	/**
	 * Factory Method
	 * @return an instance of <code>GenericInterface1<String></code>
	 */
	public static GenericInterface1<String> create(){
		return new GenericInterface1Impl<>();
	}

}


public class GenericInterface2Impl implements GenericInterface2<String>{

	@Override
	public String doSomethingMoreGeneric(String o) {
		return "somethingMoreGeneric_" + o;
	}
}

"GenericInterface1Impl" has a factory method that creates an instance of "GenericInterface1<String>".

The issue is: spring can't find a qualifying bean for the attribute "GenericInterface1.gi2" even though there's a suitable "GenericInterface2<String>" implementation (GenericInterface2Impl) in the application context.

The exact same code works perfectly with spring version 3.2.8 but fails with spring version 4.0.2. You can easily change the spring version to 3.2.8 in "pom.xml" to verify that.

Here's the exception stack trace:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'spring.test.generics.GenericInterface1Impl#0': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private spring.test.generics.GenericInterface2 spring.test.generics.GenericInterface1Impl.gi2; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [spring.test.generics.GenericInterface2] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
	at spring.test.generics.App.main(App.java:13)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private spring.test.generics.GenericInterface2 spring.test.generics.GenericInterface1Impl.gi2; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [spring.test.generics.GenericInterface2] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
	... 13 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [spring.test.generics.GenericInterface2] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1100)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
	... 15 more

Thanks,
Jair Jr


Affects: 4.0.2

Attachments:

Issue Links:

Referenced from: commits spring-projects/spring-session@0abbba0

0 votes, 6 watchers

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: regressionA bug that is also a regression

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions