Spring: No matching bean found which qualifies as autowire - java

Application-Context is correctly setup!
Heres my class scenario
public interface IManager
{
public void doStuff();
}
#Component
public abstract class ManagerAction implements IManager
{
#Async
#Override
public void doStuff()
{
//doing stuff
}
public abstract manageWorker();
}
#Component
public class Working extends ManagerAction
{
#Override
public manageWorker()
{
//some busy code
}
}
#Component
public class NotWorking extends ManagerAction
{
#Override
public manageWorker()
{
//some busy code
}
}
#Service
public class BusinessWorker
{
#Autowire
private IManager manager_;
public void preformTasks()
{
manager_.doStuff();
}
}
Heres my error
ERROR [main] (ContextLoader.java:307) - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'BusinessWorker': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.B
eanCreationException: Could not autowire field: private com.background.IManager com.background.BusinessWorker.manager_; nested exception is org.springframework.beans.
factory.NoSuchBeanDefinitionException: No matching bean of type [com.background.IManager] 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)}
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.background.IManager com.background.BusinessWorker.manager_;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.background.IManager] 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:506)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
... 28 more
Application-Context
<mvc:annotation-driven />
<task:annotation-driven />
<context:annotation-config />
<context:component-scan base-package="com.background" />

The error message says it all: you try to autowire an instance of IManager, but two different Spring components implement this interface, so Spring doesn't know which one to autowire. You need to use the #Qualifier annotation to specify which one you want Spring to autowire.

Related

UnsatisfiedDependencyException: Error creating bean with name in 2.4.1 Spring Boot

main Class:
package *.*.*;
#SpringBootApplication
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
DBUtils.java
package *.*.*.dataaccess.dbutils;
#Service
public class DBUtils {
#Autowired
UserRepository userRepository;
public UserEntity getUserEntityById(String id) {
return userRepository.findById(id);
}
}
Repository Class:
package *.*.*.dataaccess.repository;
#Repository
public interface UserRepository extends JpaRepository<UserEntity, UserIdentity> {
UserEntity findById(String id);
}
and also UserEntity java class is in package *.*.*.dataaccess.dao;
Test Class:
#SpringBootTest
class UserApplicationTests {
#Autowired
DBUtils utils; // issue is with this
#Test
void contextLoads() {
}
}
While doing maven test for entire project and getting the below error:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'DBUtils': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type '...dataaccess.repository.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type '...dataaccess.repository.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
I have used #Service on DBUtils and #Repository on JpaRepository but still getting the above error and using springboot is 2.4.1.
Can anyone please help here?

NoSuchBeanDefinitionException for deep inheritance

I have a Spring boot application. My repository is written in the following way:
An interface:
#NoRepositoryBean
public interface MyQueryRepository {
int checkThis(String this);
int checkThisAndThat(String this, String that);
}
An abstract Class:
public abstract class AbstractMyQueryRepository implements MyQueryRepository {
#Override
public int checkThis(String this) {...}
#Override
public int checkThisAndThat(String this, String that) {...}
}
then the implementation:
#Transactional(TVServiceDbConfigAtlanta.TV_TRANSACTION_MANAGER_NAME_ATLANTA)
#Repository
public class MyQueryRepositoryAtlanta extends AbstractMyQueryRepository {
#Autowired
public MyQueryRepositoryAtlanta (
#Qualifier(TVServiceDbConfigAtlanta.TV_DATA_SOURCE_BEAN_NAME_ATLANTA) final DataSource dataSource) {
super(dataSource);
}
}
When I try to autowire MyQueryRepositoryAtlanta in my UT in the following way:
#ExtendWith(SpringExtension.class)
#DataJpaTest
#ActiveProfiles("test")
class MyQueryRepositoryAtlantaTest{
#Autowired
private MyQueryRepositoryAtlanta myQueryRepositoryAtlanta ;
#Test
void checkThisTest() {
assertThat(myQueryRepositoryAtlanta.checkThis("ABC")).isEqualTo(1);
}
#TestConfiguration
#Profile("test")
#Import(TVServiceDbConfigAtlanta.class)
public static class Config {
}
}
I get the following error:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name
'com.myapp.MyQueryRepositoryAtlantaTest': Unsatisfied dependency
expressed through field 'myQueryRepositoryAtlanta '; nested exception
is org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'com.myapp.AbstractMyQueryRepository '
available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
~[spring-beans-5.0.8.RELEASE.jar:5.0.8.RELEASE] at
org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91)
~[spring-beans-5.0.8.RELEASE.jar:5.0.8.RELEASE] at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372)
~[spring-beans-5.0.8.RELEASE.jar:5.0.8.RELEASE] at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1341)
~[spring-beans-5.0.8.RELEASE.jar:5.0.8.RELEASE] at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:393)
~[spring-beans-5.0.8.RELEASE.jar:5.0.8.RELEASE] at
org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)
~[spring-test-5.0.8.RELEASE.jar:5.0.8.RELEASE] [...]
I am not sure I understand why, since:
The bean that I am testing is annotated as #Repository and
There is no other bean called in the same way
I also checked similar answers in SOF but they are not applicable because of the particular structure that I use. Any idea about how to solve the issue?

Spring #Conditional: Error Message

#Configuration
public class MyConfig {
#Bean
public Foobar foobar(#Value("${my.value}") String v) {
return new Foobar(v);
}
}
#Component
public class MyComp {
private final Foobar foobar;
public MyComp(Foobar foobar) {
this.foobar = foobar;
System.out.println(foobar);
}
}
If my.value is not set, I will get this error message
java.lang.IllegalArgumentException: Could not resolve placeholder 'my.value' in string value "${my.value}"
Now my.value is also secured by #ConditionalOnProperty("my.value")
#Configuration
public class MyConfig {
#ConditionalOnProperty("my.value")
#Bean
public Foobar foobar(#Value("${my.value}") String v) {
return new Foobar(v);
}
}
If my.value is not set, I will get this error message
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myComp' defined in file [/home/stephan/workspaces/workspace_mercateo/demo/target/classes/com/example/MyComp.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type [com.example.Foobar] found for dependency [com.example.Foobar]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.Foobar] found for dependency [com.example.Foobar]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
[...]
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.Foobar] found for dependency [com.example.Foobar]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
Though spring recognizes that my.value is missing there is nothing about this in the output log.
Is there a way to configure spring so that
1) #Conditional is used
and
2) error message contains "my.value is missing"
?

Cannot autowire bean that overrides a method that is overriden in parent

In our project we have a structure similiar to code below. If I uncomment the specified block Spring will fail to autowire PrintService in the PrintController
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'PrintController': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private printService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [MyPrintService] 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)}
Why is Spring having issues with it?
#Controller
public class PrintController {
#Autowired
private MyPrintService printService;
}
#Service
public class MyPrintService extends AbstractPrintService<MyModel> {
/* uncomment this block to get error
#Override
public void print(MyModel model){
//do stuff
}*/
}
public abstract class AbstractPrintService<M> extends CommonAbstractPrintService<M> {
}
public abstract class CommonAbstractPrintService<M> implements PrintService<M> {
#Override
public void print(M model){
//do common stuff
}
}
public interface PrintService<M> {
void print(M model);
}
The solution was to autowire the bean using interface. So instead of:
#Autowired
private MyPrintService printService;
I used
#Autowired
private PrintService printService;
And it suddenly worked. But I have no Idea why Spring was offended by that override. Would be glad if anyone could explain that! Thanks!

Could not autowire field performing Junit Tests in Spring 3.2.8 & junit 4.4

Having this class, I am havin to perform some tests with the library junit 4.4. without success
public class GeolocationServiceTest extends AbstractAnnotationAwareTransactionalTests {
private static final String GEOJSON_FILE = "geojson_demo.geojson";
private static final String GEOJSON_FILE2 = "geojson_ecat.geojson";
private static final String ADDRESS = "rue commerce+PARIS";
private static final String ADDRESS2 = "Gravilliers 12, Paris";
private static final String[] CONFIG_LOCATIONS = new String[] {
"classpath:com/devices/testServiceContext.xml",
"classpath:com/devices/testApplicationContext.xml", "classpath:com/devices/testDatabaseMessageSource.xml", "classpath:com/devices/propertyeditorsContext.xml" };
#Autowired
private CompanyDao companyDao;
#Autowired
private GeolocationService geolocationService;
...
}
I got this strange error saying that is not posible the injection of a bean, but this bean exists in the file testServiceContext.xml so i don't understand it at all.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.devices.services.GeolocationServiceTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.devices.services.geolocation.GeolocationService com.devices.services.GeolocationServiceTest.geolocationService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.devices.services.geolocation.GeolocationService] 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:289)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:376)
at org.springframework.test.AbstractDependencyInjectionSpringContextTests.injectDependencies(AbstractDependencyInjectionSpringContextTests.java:210)
at org.springframework.test.AbstractDependencyInjectionSpringContextTests.prepareTestInstance(AbstractDependencyInjectionSpringContextTests.java:184)
at org.springframework.test.AbstractSingleSpringContextTests.setUp(AbstractSingleSpringContextTests.java:103)
at junit.framework.TestCase.runBare(TestCase.java:139)
at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:79)
at org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests.access$001(AbstractAnnotationAwareTransactionalTests.java:74)
at org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests$1.run(AbstractAnnotationAwareTransactionalTests.java:179)
at org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests.runTest(AbstractAnnotationAwareTransactionalTests.java:287)
at org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests.runTestTimed(AbstractAnnotationAwareTransactionalTests.java:258)
at org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests.runBare(AbstractAnnotationAwareTransactionalTests.java:176)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.devices.services.geolocation.GeolocationService com.devices.services.GeolocationServiceTest.geolocationService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.devices.services.geolocation.GeolocationService] 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:517)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)
... 25 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.devices.services.geolocation.GeolocationService] 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:988)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:489)
... 27 more
here you can see the file testServiceContext.xml:
<!-- Scan for services -->
<context:component-scan base-package="com.devices.services.impl" />
<context:component-scan base-package="com.devices.services.geolocation" />
and the class seems to be well declared
package com.devices.services.geolocation
#Service(value = "geolocationService")
public interface GeolocationService {
....
}
This exception you will receive in below scenario:
#Service(value = "geolocationService")
public interface GeolocationService {
....
}
Now you have created the implementation of above interface
public class GeolocationServiceImpl implements GeolocationService {
..........
}
Now if you try to inject GeolocationService through #Autowired, will receive exception :
No qualifying bean of type [com.devices.services.geolocation.GeolocationService] found for dependency
Solution for it:
1) Either put #Component annotation on GeolocationServiceImpl as below:
#Component
public class GeolocationServiceImpl implements GeolocationService {
..........
}
2) Define it in spring-context.xml as:-
<bean id="geolocationService" class="com.devices.services.geolocation.GeolocationServiceImpl" />
In-short you need to make the Spring ApplicationContext aware of implementation of your interface.

Categories

Resources