Spring MVC Controller Test Case not working - java

#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes=BaseTestConfig.class)
#WebAppConfiguration
public class BookDetailsControllerTestCase {
private MockMvc mockMvc;
#Autowired
private WebApplicationContext wac;
/**
*
*/
private BookDetailsController fixture = new BookDetailsController();
public BookDetailsController getFixture() {
return fixture;
}
public void setFixture(BookDetailsController fixture) {
this.fixture = fixture;
}
/**
* #throws java.lang.Exception
*/
#BeforeClass
public static void setUpBeforeClass() throws Exception {
}
/**
* #throws java.lang.Exception
*/
#AfterClass
public static void tearDownAfterClass() throws Exception {
}
/**
* #throws java.lang.Exception
*/
#Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
/**
* #throws java.lang.Exception
*/
#After
public void tearDown() throws Exception {
}
#Test
public void testGetBookDetails() {
fail("Not yet implemented");
}
}
This is my test case for the getBookDetails method of the Book Details Controller. However, I am getting the following error trace.
Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener#58e34201] to prepare test instance [com.sapestore.controller.test.BookDetailsControllerTestCase#30027d3e]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:161)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:101)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:331)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:213)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:290)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:292)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176)
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:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'accountController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.sapestore.service.AccountService com.sapestore.controller.AccountController.accountService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.sapestore.service.AccountService] 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:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:132)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:59)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:250)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
... 27 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.sapestore.service.AccountService com.sapestore.controller.AccountController.accountService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.sapestore.service.AccountService] 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)
... 43 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.sapestore.service.AccountService] 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:1103)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 45 more
This is my folder structure
/webapp/WEb_INF/application-context.xml
/src/test/resources/test-application-context.xml
package com.sapestore.controller.test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#ComponentScan("com.sapestore")
#EnableWebMvc
public class BaseTestConfig {
#Bean
public InternalResourceViewResolver setupViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/");
resolver.setSuffix(".jsp");
return resolver;
}
}
This is the BaseTestConfig.java file
Please help me run the test case!

The stacktrace says that spring trys to instantiate an accountService. This service seems to be an dependency for your AccountController. But spring don't find anything that cann be bound to this dependency in your controller.
Have you anntotated your service correctly so spring can identify the class as spring bean (for more information read the reference: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-stereotype-annotations).
If the service is annotated correctly and it's still not working, can you provide some code from your controller and your service?

Related

UnsatisfiedDependencyException using #DataJpaTest with SpringBoot

I am using SpringBoot and I have a DataJpaTest, but when I run the Test class, I get this StackTrace:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:47)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'restTemplate' defined in br.com.mobtrack.api.MobTrackApplication: Unsatisfied dependency expressed through method 'restTemplate' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.web.client.RestTemplateBuilder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1134)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1028)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:111)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 28 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.web.client.RestTemplateBuilder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1474)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1102)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
I think this happens because I have a RestTemplate bean inside my Application class like this:
#SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
}
This is my Test Class:
#RunWith(SpringRunner.class)
#DataJpaTest
public class CityRepositoryTest {
#Autowired
private TestEntityManager entityManager;
#Autowired
private CityRepository cityRepository;
private City city;
#Before
public void init() {
city = new City();
city.setName("New York");
city.setImage("http://www.mockimage.com");
}
#Test
public void findByNameShouldReturnCity() throws Exception {
this.entityManager.persist(city);
Optional<City> hasCity = this.cityRepository.findByNameIgnoreCase("New York");
city = hasCity.get();
assertThat(city.getId()).isNotNull();
assertThat(city.getName()).isEqualTo("New York");
assertThat(city.getImage()).isEqualTo("http://www.mockimage.com");
}
#Test
public void findByNameStartingWithShouldReturnCity() throws Exception {
this.entityManager.persist(city);
Optional<City> hasCity = this.cityRepository.findByNameStartingWithIgnoreCase("New");
city = hasCity.get();
assertThat(city.getId()).isNotNull();
assertThat(city.getName()).isEqualTo("New York");
assertThat(city.getImage()).isEqualTo("http://www.mockimage.com");
}
#Test
public void findByNameWhenNoCityShouldReturnFalse() throws Exception {
this.entityManager.persist(city);
Optional<City> hasCity = this.cityRepository.findByNameStartingWithIgnoreCase("Ohaio");
assertThat(hasCity.isPresent()).isFalse();
}
}
Any help is welcome,Thanks a lot!
I didn't like the other solution as I did want my application to use the spring provided RestTemplateBuilder since it provides some default message converters and other functionality I needed when running my app.
However I found 2 ways to alter my test to get my DataJpaTest's to run, not sure which is best:
Method One - provide a mock RestTemplate in your test.
#RunWith(SpringRunner.class)
#DataJpaTest
public class SomeTest {
#MockBean
private RestTemplate restTemplate;
Method Two - add AutoConfigureWebClient annotation so spring will wire the RestTemplateBuilder
#RunWith(SpringRunner.class)
#DataJpaTest
#AutoConfigureWebClient
public class SomeTest {
With both ways I could keep my existing configured rest template in my application class:
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
As the error is clearly saying - there is no qualifying bean of type RestTemplateBuilder being available for use of RestTemplate bean building.
The bean for RestTempalteBuilder is injected into context by the spring boot starter for web. There is generally no need to declare a RestTemplateBuilder bean into the context as it is already provided by the spring-boot auto-configuration. If the project is a spring-boot application this will work out of box as intended.
If required, one can customise it by creating a new one in the application configuration.Something like below:
#Bean
public RestTemplateBuilder restTemplateBuilder() {
return new RestTemplateBuilder()
.basicAuthorization("abc", "password");
}
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
And if no real reason to customise it, you could rather have a simpler bean definition for RestTemplate as below:
#Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}

Spring in Action Chapter 2 changing XML bean to JavaConfig doesn't pass the test

Below is my Bean configuration code, but the configuration doesn't pass the test as it says it failed to load ApplicationContext. Is there something I'm doing wrong? I added #Autowire to methods of each class that's needed (except for interface method), but I still have no idea why it's not loading
package soundsystems;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class CDPlayerConfig
{
#Bean
public CompactDisc sgtPeppers()
{
return new SgtPeppers();
}
#Bean(name = "SgtPepperPlayer")
public CDPlayer cdPlayer()
{
return new CDPlayer(sgtPeppers());
}
#Bean(name = "AnyCDPlayer")
public CDPlayer cdPlayer(CompactDisc cd)
{
return new CDPlayer(cd);
}
#Bean
public BlankDisc reallyBlankDisc()
{
return new BlankDisc();
}
#Bean
public BlankDisc blankDisc()
{
BlankDisc bd = new BlankDisc();
String title = "Sgt. Pepper's Lonely Hearts Club Band";
String artist = "The Beatles";
List<String> tracks = new ArrayList<String>();
tracks.add("Sgt. Pepper's Lonely Hearts Club Band");
tracks.add("With a Little Help from My Friends");
tracks.add("Lucy in the Sky with Diamonds");
tracks.add("Getting Better");
tracks.add("Fixing a Hole");
bd.setTitle(title);
bd.setArtist(artist);
bd.setTracks(tracks);
return bd;
}
#Bean
public Discography beatlesDiscography()
{
Discography dg = new Discography();
String artist = "The Beatles";
CompactDisc SgtPeppers = new SgtPeppers();
CompactDisc WhiteAlbum = new WhiteAlbum();
CompactDisc HardDaysNight = new HardDaysNight();
CompactDisc Revolver = new Revolver();
List<CompactDisc> cds = new ArrayList<CompactDisc>();
cds.add(SgtPeppers);
cds.add(WhiteAlbum);
cds.add(HardDaysNight);
cds.add(Revolver);
dg.setArtist(artist);
dg.setCDs(cds);
return dg;
}
}
package soundsystems;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest
{
#Rule
public final SystemOutRule log = new SystemOutRule().enableLog();
#Autowired
private CompactDisc cd;
#Autowired
private MediaPlayer player;
#Test
public void cdShouldNotBeNull()
{
assertNotNull(cd);
}
#Test
public void play()
{
player.play();
assertEquals("Playing Sgt. Pepper's Lonely Hearts Club Band" + " by The Beatles\n", log.getLog());
}
}
Thanks for having a look.
edit: Error
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:249)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'AnyCDPlayer': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void soundsystems.CDPlayer.setCompactDisc(soundsystems.CompactDisc); nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [soundsystems.CompactDisc] is defined: expected single matching bean but found 3: blankDisc,sgtPeppers,reallyBlankDisc
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:125)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:109)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:261)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 25 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void soundsystems.CDPlayer.setCompactDisc(soundsystems.CompactDisc); nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [soundsystems.CompactDisc] is defined: expected single matching bean but found 3: blankDisc,sgtPeppers,reallyBlankDisc
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:661)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 41 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [soundsystems.CompactDisc] is defined: expected single matching bean but found 3: blankDisc,sgtPeppers,reallyBlankDisc
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1126)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:618)
... 43 more
I believe that Spring's #Autowired default mode is by type. It means that Spring will try to autowire bean by interface type, btw you have 3 beans with same interface and Spring got confused which one to choose. If you want to achieve autowiring by name you should use #Qualifier: #Qualifier("beanname")
The error is quite clear:
Could not autowire method: public void soundsystems.CDPlayer.setCompactDisc(soundsystems.CompactDisc);
nested exception is
org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [soundsystems.CompactDisc] is defined:
expected single matching bean but found 3: blankDisc,sgtPeppers,reallyBlankDisc
You annotated you setCompactDisc() method in CDPlayer with #Autowired, so Spring tries to call it with a bean of type CompactDisc, but it has 3 of them, and thus can't decide which one to inject. Don't annotate this method with Autowired. Or even better, remove that method, since the CompactDisc is already initialized by the constructor.

No qualifying bean of type found for dependency

I am trying to write basic spring project. However, I have a big issue using `#Autowired through the Service. I didn't find the problem and got the error bellow:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testeRS': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: br.com.lazycat.service.TesteServiceImpl br.com.lazycat.endpoint.TesteRS.testeService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [br.com.lazycat.service.TesteServiceImpl] 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:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:658)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:672)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:543)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:484)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1241)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1154)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1041)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4969)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5255)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: br.com.lazycat.service.TesteServiceImpl br.com.lazycat.endpoint.TesteRS.testeService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [br.com.lazycat.service.TesteServiceImpl] 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)
... 29 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [br.com.lazycat.service.TesteServiceImpl] 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:1103)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 31 more
mar 05, 2015 11:23:09 PM org.apache.catalina.core.StandardContext loadOnStartup
GRAVE: Servlet /lazycat threw load() exception
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [br.com.lazycat.service.TesteServiceImpl] 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:1103)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
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:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:658)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:672)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:543)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:484)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1241)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1154)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1041)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4969)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5255)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
My AppConfig:
package br.com.lazycat.config;
import java.util.Properties;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages={"br.com.lazycat.repository"})
#ComponentScan({"br.com.lazycat.endpoint", "br.com.lazycat.config", "br.com.lazycat.service", "br.com.lazycat.model", "br.com.lazycat.repository"} )
public class AppConfig {
private static final String DATABASE_DRIVER = "org.postgresql.Driver";
private static final String DATABASE_URL = "jdbc:postgresql://localhost:5432/postgres";
private static final String DATABASE_USERNAME = "postgres";
private static final String DATABASE_PASSWORD = "123qwe";
private static final String HIBERNATE_DIALECT = "org.hibernate.dialect.PostgreSQLDialect";
private static final String HIBERNATE_SHOW_SQL = "true";
private static final String ENTITYMANAGER_PACKAGES_TO_SCAN = "br.com.lazycat.model";
public static final String USER_CACHE = "userRestCache";
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DATABASE_DRIVER);
dataSource.setUrl(DATABASE_URL);
dataSource.setUsername(DATABASE_USERNAME);
dataSource.setPassword(DATABASE_PASSWORD);
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.POSTGRESQL);
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setShowSql(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setDataSource(dataSource());
factory.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
return factory;
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
sessionFactoryBean.setHibernateProperties(hibProperties());
return sessionFactoryBean;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", HIBERNATE_DIALECT);
properties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
return properties;
}
#Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
entityManagerFactory().getObject() );
return transactionManager;
/*HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;*/
}
}
RestController:
#RestController
#RequestMapping(value = "/teste", produces = "application/json")
public class TesteRS {
#Autowired
TesteServiceImpl testeService;
#RequestMapping(method=RequestMethod.POST, value="/piroca/{nome}")
private void testPut(#PathVariable("nome") String nome) {
testeService.save(nome);
}
}
Service - Interface
public interface TesteService {
public void save(String nome);
}
Service
#Service("testeService")
#Transactional
public class TesteServiceImpl implements TesteService {
#Autowired
TesteRepository testeRepository;
public void save(String nome) {
Teste tst = new Teste();
tst.setName(nome);
System.out.println(tst);
testeRepository.save(tst);
}
}
Repository
#Repository
public interface TesteRepository extends JpaRepository<Teste, Integer>{
}
I appreciate your help. Thanks!
Try this in your controller. You generally autowire to your interface type and not impl.
public class TesteRS {
#Autowired
#Qualifier("testeService")
TesteService testeService;
Remove the qualifier from #Service. Change #Service("testeService") to simply #Service.
Do not inject TesteServiceImpl directly. Change #Autowired TesteServiceImpl testeService to #Autowired TesteService testeService.
#Service(<name>) assigns <name> to the bean instance created by Spring. This is not necessary unless you have multiple implementations of a component. For example, if you had:
interface UserRepository {}
class UserLdapRepository implements UserRepository {}
class UserSamlRepository implements UserRepository {}
you would have two components in the Spring component registry that implement UserRepository. Then, if you wanted to #Autowired UserRepository userRepository, there will be an ambiguity in which implementation of UserRepository should be autowired. It is in this situation that #Service(<name>) would be useful.
When your class implements an interface, it is better to inject the interface instead of the class. This becomes mandatory if Spring AOP is used with its default configuration. In your case #EnableTransactionManagement triggers AOP that in its default configuration creates interface proxies. Therefore, a TesteService (and not a TesteServiceImpl) proxy is created. So, Spring rightly complains about there being no TesteServiceImpl instance when you try to inject it.

How to Autowire Interface with Implementation

I have been Googling the answer for a long time, but I am certain I am missing something that would bring this all together. I am just not sure what. It is failing on running the Spring server with error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.test.abc.sv.dao.TestDAO com.test.abc.sv.controller.TestController.testDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.test.abc.sv.dao.TestDAO] 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:293)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)
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:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
at com.test.abc.sv.SpringLaunch.main(SpringLaunch.java:26)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.test.abc.sv.dao.TestDAO com.test.abc.sv.controller.TestController.testDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.test.abc.sv.dao.TestDAO] 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:509)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:290)
... 16 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.test.abc.sv.dao.TestDAO] 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:1118)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:967)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:481)
... 18 common frames omitted
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.test.abc.sv.dao.TestDAO com.test.abc.sv.controller.TestController.testDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.test.abc.sv.dao.TestDAO] 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:293)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)
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:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
at com.test.abc.sv.SpringLaunch.main(SpringLaunch.java:26)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.test.abc.sv.dao.TestDAO com.test.abc.sv.controller.TestController.testDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.test.abc.sv.dao.TestDAO] 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:509)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:290)
... 16 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.test.abc.sv.dao.TestDAO] 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:1118)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:967)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:481)
... 18 more
So I am running the application from
SpringLaunch.class - com.test.abc.sv
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class SpringLaunch extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}
private static Class<SpringLaunch> applicationClass = SpringLaunch.class;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dataSource.setUrl("jdbc:oracle:thin:#(DESCRIPTION ="
+"(LOAD_BALANCE=on)"
+"(FAILOVER=on)"
+"(ADDRESS=(PROTOCOL=tcp)(HOST=56.276.152.217)(PORT=1521))"
+"(ADDRESS=(PROTOCOL=tcp)(HOST=56.276.152.218)(PORT=1521))"
+"(CONNECT_DATA=(SERVICE_NAME=test.abc.com)))");
dataSource.setUsername("DevUser");
dataSource.setPassword("Credential");
return dataSource;
}
#Bean
public TestDAO testDAO() {
return new TestDAOImpl(dataSource());
}
}
TestController.class - com.test.abc.sv.controller
#RestController
#RequestMapping("/test")
public class TestController{
#Autowired
TestDAO testDao;
final static Logger logger = Logger.getLogger(TestController.class);
#RequestMapping(value="/setup", method = RequestMethod.GET)
public Message setupTest(#RequestParam(value="id", required=true) String testNumber) {
String testMsg = new String();
try{
testMsg = testDao.prepDatabase(testNumber);
}
catch(SQLException e)
{
//Log e.getMessage();
logger.error(e.getMessage());
System.out.println(e.getMessage());
return new Message("-1");
}
return new Message(testMsg);
}
#RequestMapping(value="/teardown", method = RequestMethod.GET)
public Message teardownTest(#RequestParam(value="id", required=true) String testNumber) {
String testMsg = new String();
try{
testMsg = testDao.removeTestData(testNumber);
}
catch(SQLException e)
{
//Log e.getMessage();
logger.error(e.getMessage());
System.out.println(e.getMessage());
return new Message("-1");
}
return new Message(testMsg);
}
}
TestDAO.class - com.test.abc.sv.dao Interface
public interface TestDAO {
public String prepDatabase(String testNumber)
throws SQLException;
public String removeTestData(String testNumber)
throws SQLException;
}
`TestDAOImpl.class - com.test.abc.sv.dao'
#Component
public class TestDAOImpl implements TestDAO{
private Log log = LogFactory.getLog(TestDAOImpl.class);
private JdbcTemplate jdbcTemplate;
public TestDAOImpl(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
#Override
public String prepDatabase(String testNumber)
throws SQLException {
//Impl Stuff
}
#Override
public String removeTestData(String testNumber)
throws SQLException {
//Impl Stuff
}
}
From the documentation of #ComponentScan:
If specific packages are not defined scanning will occur from the package of the class with this annotation.
Your Application class is in com.test.abc.sv.controller package according to your question. So everything in com.test.abc.sv.controller and its subppackages will be scanned, but that doesn't include your custom configuration or services because they are not in supbackages of com.test.abc.sv.controller.
So the solution would be to move the Application class to for example com.test.abc package or explicitly define the package to scan as com.test.abc for instance.
Also I'm not really sure why are you using that custom configuration class. You can configure data source using Spring Boot properties.
And as for the DAO/service bean declarations in your configuration class, that's what the #Service or #Repository annotation for service and dao respectively are for. So I would suggest getting rid of those too. If you don't you will most likely get another exception, because your beans will be registered once by the component scan and second time from your configuration class, which will result in NoUniqueBeanDefinitionException.

Problems with Spring Java Config and #EnableTransactionManagement

I am migrating away from XML config for Spring context configuration. Instead when I try to use the functionally equivalent #EnableTransactionManagement on a Spring 4.0.3.RELEASE Java Configuration, my Spring context fails to instantiate with the following exception:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:319)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:236)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:134)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:113)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:103)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:74)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseMySQLTest.TestConfig': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.transaction.intercep...skipping...
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1558)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
... 45 more
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration.transactionAdvisor()] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionInterceptor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'transactionManager' is required
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:586)
... 62 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionInterceptor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'transactionManager' is required
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
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.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:324)
at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$83a12634.transactionInterceptor()
at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration.transactionAdvisor(ProxyTransactionManagementConfiguration.java:45)
at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$83a12634.CGLIB$transactionAdvisor$0()
at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$83a12634$$FastClassBySpringCGLIB$$cc829ae.invoke()
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$83a12634.transactionAdvisor()
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
... 63 more
Caused by: java.lang.IllegalArgumentException: Property 'transactionManager' is required
at org.springframework.transaction.interceptor.TransactionAspectSupport.afterPropertiesSet(TransactionAspectSupport.java:195)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
... 82 more
This happens to obtain in a unit test, but when it works here, I can use it in production code.
Here is my unit test base class where the Spring wiring occurs:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {PropertyPlaceholderConfigurer.class, BaseMySQLTest.TestConfig.class})
public class BaseMySQLTest extends AbstractTransactionalJUnit4SpringContextTests {
#Configuration
#Import(DaoConfig.class)
#PropertySource("classpath:/jdbc.properties")
#EnableTransactionManagement
public static class TestConfig {
#Bean
public PlatformTransactionManager providesTransactionManager(ListableBeanFactory beanFactory) {
return new DataSourceTransactionManager(beanFactory.getBean(DataSource.class));
}
}
}
and here is a subclass that uses this base class and config:
public class UserDaoImplTest extends BaseMySQLTest {
#Autowired
private UserDao userDao;
#Test
public void testById() throws Exception {
jdbcTemplate.execute("insert into users (email) values ('bob#example.com')");
...
}
}
As one can see, my Spring TestConfig has a transaction manager bean defined, which according to the Javadoc
http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html
means I do not have to name the bean (though I have named it in an attempt to get this to work). In fact, the Spring context is behaving as if configured with XML config in the face of no bean explicitly named "transactionManager".
What is my Java Config missing such that the Spring context cannot use this transaction manager bean to satisfy its requirements at instantiation time?
Thank you for any helpful observations.
EDIT:
(I'm not sure where this edit should go, so I try here. ae6rt)
Here is the new test class, which results in the same error as the original work:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {BaseMySQLTest.TestConfig.class})
public class BaseMySQLTest extends AbstractTransactionalJUnit4SpringContextTests {
protected int lastInsertId() {
return jdbcTemplate.queryForInt("select LAST_INSERT_ID()");
}
#Autowired
private UserDao userDao;
#Test
public void testById() throws Exception {
jdbcTemplate.execute("insert into mgdb.users (email) values ('bob#example.com')");
int userId = lastInsertId();
Optional xoomUserOptional = userDao.byId(userId);
assertThat(xoomUserOptional.isPresent(), equalTo(true));
XoomUser user = xoomUserOptional.get();
assertThat(user.getEmailAddress(), equalTo("bob#example.com"));
}
#Configuration
#Import(DaoConfig.class)
#PropertySource("classpath:/jdbc.properties")
#EnableTransactionManagement
public static class TestConfig {
#Bean
public PlatformTransactionManager providesTransactionManager(ListableBeanFactory beanFactory) {
return new DataSourceTransactionManager(beanFactory.getBean(DataSource.class));
}
}
}
I didn't actualy need the property config here
#ContextConfiguration(classes = {BaseMySQLTest.TestConfig.class})
so I removed it. Hope this meets the spirit of this round.
Looks like the only change should be to name your transaction manager bean name to "transactionManager":
public static class TestConfig {
#Autowired
private DataSource datasource;
#Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(datasource);
}
}
EDIT :
Can you try these additional things:
.1. Remove PropertyPlaceHolderConfigurer from here.. #ContextConfiguration(classes = {PropertyPlaceholderConfigurer.class, BaseMySQLTest.TestConfig.class}), that is not how PropertyPlaceholderConfigurer is used, you have to do it this way:
#Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
PropertySourcesPlaceholderConfigurer placeholderConfigurer = new PropertySourcesPlaceholderConfigurer();
ClassPathResource resource = new ClassPathResource("/META-INF/spring/database.properties");
placeholderConfigurer.setLocation(resource);
return placeholderConfigurer;
}
Also, just for test, can you move your actual test to the base class also and see if one of these configuration works out for you. I tested in my own machine and it seems to work nicely with Spring 4.0.2+.

Categories