Service not been injected in Spring controller test with spring-test-mvc - spring

I'm attempting to build a set of unit/integration tests for a Restful API Server I have created using Spring MVC 3.1.1.
I'm trying to use the Spring-test-mvc.
I'm relatively new to Spring and hence spring-test-mvc.
I will include relevant sections of my code to give you a feel for how I have structured it:
PurchaseController:
#Controller
public class PurchaseController
{
#Autowired
private IPurchaseService purchaseService;
#RequestMapping(value = "purchases", method = RequestMethod.GET)
#ResponseBody
public final List<Purchase> getAll()
{
return purchaseService.getAll();
}
}
PurchaseService:
#Service
public class PurchaseService implements IPurchaseService
{
#Autowired
private IPurchaseDAO purchaseDAO;
public PurchaseService()
{
}
#Transactional
public List<Purchase> getAll()
{
return purchaseDAO.findAll();
}
}
PurchaseDAO:
#Repository
public class PurchaseDAO extends AbstractJpaDAO<Purchase> implements
IPurchaseDAO
{
#PersistenceContext
EntityManager entityManager;
public PurchaseDAO()
{
setClazz(Purchase.class);
}
}
AbstractJpaDAO:
public abstract class AbstractJpaDAO<T extends Serializable> implements
IAbstractJpaDAO<T> {
private Class<T> clazz;
#PersistenceContext
EntityManager entityManager;
public void setClazz(final Class<T> clazzToSet) {
this.clazz = clazzToSet;
}
public List<T> findAll() {
return entityManager.createQuery("from " + clazz.getName())
.getResultList();
}
}
Here is my controller test:
public class PurchaseControllerTest extends AbstractControllerTest
{
#Autowired
private IPurchaseService purchaseService;
#Autowired
private PurchaseController purchaseController;
private MockMvc mockMvc;
#Before
public void setup()
{
// Test Purchase
Purchase purchase = new Purchase();
purchase.setPan(5412311111111121l);
purchase.setCvc((short) 122);
purchase.setExpiry("1215");
purchase.setMerchantName("TestMerchant");
purchase.setMerchantType("Airline");
purchase.setTransactionAmount(new BigDecimal("300.99"));
mockMvc = MockMvcBuilders.standaloneSetup(purchaseController).build();
purchaseService.addPurchase(purchase);
}
#Test
public void testGetAll() throws Exception
{
this.mockMvc
.perform(get("/purchase").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().type(MediaType.APPLICATION_JSON));
}
}
AbstractControllerTest:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {ControllerTestConfig.class}, loader=AnnotationConfigContextLoader.class)
#ActiveProfiles("test")
public class AbstractControllerTest
{
}
ControllerTestConfig:
#Configuration
#Profile("test")
public class ControllerTestConfig {
#Bean
public PurchaseService purchaseService()
{
return new PurchaseService();
}
#Bean
public PurchaseDAO purchaseDAO()
{
return new PurchaseDAO();
}
#Bean
public EntityManagerFactory entityManager()
{
return new LocalEntityManagerFactoryBean().getObject();
}
}
I get the following Error when running my test via Eclipse's JUnit:
2012-07-08 16:16:00,017 TRACE [main] o.s.c.s.GenericApplicationContext [AbstractApplicationContext.java:322] Publishing event in org.springframework.context.support.GenericApplicationContext#42b307f0: org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.support.GenericApplicationContext#42b307f0: startup date [Sun Jul 08 16:15:59 IST 2012]; root of context hierarchy]
2012-07-08 16:16:00,018 DEBUG [main] o.s.t.c.TestContext [TestContext.java:150] Storing ApplicationContext for test class [class com.app.controller.PurchaseControllerTest] in cache under key [[MergedContextConfiguration#2f8a49e0 testClass = PurchaseControllerTest, locations = '{}', classes = '{class com.app.spring.testing.ControllerTestConfig}', activeProfiles = '{test}', contextLoader = 'org.springframework.test.context.support.AnnotationConfigContextLoader']].
2012-07-08 16:16:00,019 TRACE [main] o.s.b.CachedIntrospectionResults [CachedIntrospectionResults.java:222] Getting BeanInfo for class [com.app.controller.PurchaseControllerTest]
2012-07-08 16:16:00,022 TRACE [main] o.s.b.CachedIntrospectionResults [CachedIntrospectionResults.java:238] Caching PropertyDescriptors for class [com.app.controller.PurchaseControllerTest]
2012-07-08 16:16:00,022 TRACE [main] o.s.b.CachedIntrospectionResults [CachedIntrospectionResults.java:250] Found bean property 'class' of type [java.lang.Class]
2012-07-08 16:16:00,023 TRACE [main] o.s.b.CachedIntrospectionResults [CachedIntrospectionResults.java:250] Found bean property 'mockMvc' of type [org.springframework.test.web.server.MockMvc]
2012-07-08 16:16:00,026 DEBUG [main] o.s.b.f.a.InjectionMetadata [InjectionMetadata.java:60] Found injected element on class [com.app.controller.PurchaseControllerTest]: AutowiredFieldElement for private com.app.service.IPurchaseService com.app.controller.PurchaseControllerTest.purchaseService
2012-07-08 16:16:00,026 DEBUG [main] o.s.b.f.a.InjectionMetadata [InjectionMetadata.java:60] Found injected element on class [com.app.controller.PurchaseControllerTest]: AutowiredFieldElement for private com.app.controller.PurchaseController com.app.controller.PurchaseControllerTest.purchaseController
2012-07-08 16:16:00,027 DEBUG [main] o.s.b.f.a.InjectionMetadata [InjectionMetadata.java:85] Processing injected method of bean 'com.app.controller.PurchaseControllerTest': AutowiredFieldElement for private com.app.service.IPurchaseService com.app.controller.PurchaseControllerTest.purchaseService
2012-07-08 16:16:00,034 ERROR [main] o.s.t.c.TestContextManager [TestContextManager.java:324] Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener#403ef810] to prepare test instance [com.app.controller.PurchaseControllerTest#656546ef]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.app.controller.PurchaseControllerTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.app.service.IPurchaseService com.app.controller.PurchaseControllerTest.purchaseService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.app.service.IPurchaseService] 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:287) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110) ~[spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75) ~[spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
Any ideas on why my PurchaseService is not created and injected?
UPDATE
So I added my Purchase Service Bean to ControllerTestConfig...now I get an error about my purchaseDAO.
How can I add this to my ControllerTestConfig? Does it have to be nested inside the Purchase Bean?
2012-07-08 18:30:23,029 ERROR [main] o.s.t.c.TestContextManager [TestContextManager.java:324] Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener#56da6bf4] to prepare test instance [com.app.controller.PurchaseControllerTest#df4cbee]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157) ~[spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109) ~[spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75) ~[spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321) ~[spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) [junit-4.8.1.jar:na]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) [junit-4.8.1.jar:na]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) [junit-4.8.1.jar:na]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) [junit-4.8.1.jar:na]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) [junit-4.8.1.jar:na]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) [junit-4.8.1.jar:na]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) [junit-4.8.1.jar:na]
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.junit.runners.ParentRunner.run(ParentRunner.java:236) [junit-4.8.1.jar:na]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) [.cp/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'purchaseService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.app.persistence.dao.IPurchaseDAO com.app.service.impl.PurchaseService.purchaseDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'purchaseDAO': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 0
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
I added PurchaseDAO bean to ControllerTestConfig.
Update 2
So now I'm getting a null pointer exception after adding An EntityManagerFactory Bean to my ControllerTestConfig!
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157) ~[spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109) ~[spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75) ~[spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321) ~[spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) [junit-4.8.1.jar:na]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) [junit-4.8.1.jar:na]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) [junit-4.8.1.jar:na]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) [junit-4.8.1.jar:na]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) [junit-4.8.1.jar:na]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) [junit-4.8.1.jar:na]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) [junit-4.8.1.jar:na]
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.junit.runners.ParentRunner.run(ParentRunner.java:236) [junit-4.8.1.jar:na]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) [spring-test-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) [.cp/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'purchaseService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.app.persistence.dao.IPurchaseDAO com.app.service.impl.PurchaseService.purchaseDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'purchaseDAO': Injection of persistence dependencies failed; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
Any ideas?
Thanks

This will not work as spring-test-mvc does not pick the context configuration from the ContextConfiguration of the Junit, instead you can do this(assuming that your Service beans are being loaded up someplace through ControllerTestConfig configuration):
MockMvcBuilders.annotationConfigSetup(ControllerTestConfig.class).build().perform(get("/purchase").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().type(MediaType.APPLICATION_JSON));

You will need to include some #Bean's in your test #Configuration profile.
Previously you had none, but since your update, I see that you have your PurchaseService added. Well, your PurchaseService has an #Autowired PurchaseDao which also needs to be added to your test profile.
Try adding this to ControllerTestConfig:
#Bean
public IPurchaseDao purchaseDao() {
return new PurchaseDao();
}
Your PurchaseDao uses an EntityManager which may also need to be added to your ControllerTestConfig class. (I am not very familiar with this portion, so I can't say difinitively...)

Given that you're using #ContextConfiguration (the TestContext framework) to load Spring configuration, my guess is that you want to do an integration test that involves loading your Controllers, Services, and Repositories from your Spring configuration. However, you're using the standaloneSetup method of MockMvcBuilders, which is intended for more focused unit tests that target mostly controllers (services and repositories are usually mocked out).
Consider using webApplicationContextSetup method of MockMvcBuilders. Here is an example.

I don't know if this will help you, but to inherit the context from #ContextConfiguration you need to autowire it in the test class, then after that, you can set it as a parent context of your ControllerTestConfig.class.
In my configuration, I separated my persistence configuration to be loaded from #ContextConfiguration, and the MVC configuration to be loaded from the annotationConfigSetup.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes={PersistenceJPAConfig.class})
public class PurchaseControllerTest {
#Autowired
private ApplicationContext ac;
private PurchaseService service;
private MockMvc mvc;
#Before
public void before() {
mvc = annotationConfigSetup(ControllerTestConfig.class).
setParentContext(ac).build();
service = ac.getBean(PurchaseService.class);
}
}
As the annotationConfigSetup does not know that you have an outer configuration, you must tell it directly by setting its parent context.
You cannot inject your service inside your test class, but you can recover it from the context and also make it injected into your controllers. Well, you can inject, but it won't be the same service that will be injected into your controllers. Getting it from the context you pass as parent, you guarantee that they are the same. As I mock my services, this is important.

Related

Adding #Transactional causes "java.lang.ClassCastException-->java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType" exception

I'm using Spring 3.2.11.RELEASE. I have a class like the following ...
#Repository("AssessmentImageDao")
#Transactional
public class MyObjectDao extends GenericDAO<MyObject>
{
in which the super class has
public GenericDAO() {
this.persistentClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
However, this causes the exception below ...
[ERROR]: org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener#62b9a65b] to prepare test instance [com.myco.MyTest#7a252cf1]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:122)
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:321)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
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:174)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MyObjectDao' defined in file [/Users/davea/Dropbox/workspace/core/target/classes/org/mainco/subco/myproject/dao/MyObjectDao.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.mainco.subco.myproject.dao.MyObjectDao]: Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.ClassCastException-->java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:636)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:934)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:120)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:102)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:246)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
... 25 more
Is there any way to rewrite the constructor to avoid this kind of exception or do some other global configuration that would fix the problem? I'm trying to invoice recoding each of the sub-classes of the GenericDao class.
The problem is that the #Transactional annotation is implemented by adding another layer to the class hierarchy - a proxy class that extends MyObjectDao to implement the transactional behaviour. For objects of this proxy class, this.getClass() is the proxy class, whose getGenericSuperclass() is MyObjectDao itself, not the parameterized type GenericDAO<MyObject>.
You could change the logic a bit, so that you keep looking up the getGenericSuperclass chain until you find a ParameterizedType - if the parent is a Class you try the grandparent, and so on.
Alternatively, see if you can defer the superclass lookup until the first time you actually need it (when one of the GenericDAO methods is called) rather than doing it in the constructor. While the generated proxy class extends MyObjectDao it never actually calls any of its superclass methods on this. The proxy intercepts all method calls, does the transaction logic, then delegates the business logic to a separate target object that is an instance of MyObjectDao directly rather than a subclass.
You can also use polymorphism and create a public abstract Class<? extends MyObject> getHandledType() method in GenericDAO and make every implementation introduce itself.
Or use Spring Data.

Testing Spring Security and MvcMock using a custom UserDetails implementation

I'm trying to follow this article [1] to mock security in my Spring MvcMock test.
The REST service I want to test looks like this:
#RequestMapping(value = "/something/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Void> deleteXXX(#ActiveUser AppUser user, #PathVariable(value = "id") Long id) {
...
}
where #ActiveUser is a custom implementation/extension of #AuthenticationPrincipal and AppUser is the custom UserDetails implementation.
In the test I do this:
mockMvc.perform(delete("/something/{i}", "123").with(user(new AppUser(...))));
I also added some TestExecutionLIsteners:
#TestExecutionListeners(listeners = { ServletTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, WithSecurityContextTestExecutionListener.class })
```
But it fails with:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.corp.AppUser]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.corp.AppUser.<init>()
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:885)
which is OK, as AppUser does not have a default constructor, but the framework should actually not create the user, but use the one I passed into the test.
To solve this issue during runtime I had to add AuthenticationPrincipalArgumentResolver as a HandlerMethodArgumentResolver to the web config, but how do I do this in the test case?
Is there any working example for this?
[1] https://spring.io/blog/2014/05/23/preview-spring-security-test-web-security
edit:
The testclass and its configuration looks like this:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = { MyControllerTest.DummyAppConfig.class, MyControllerTest.DummySecurityConfiguration.class })
#TestExecutionListeners(listeners = { ServletTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, WithSecurityContextTestExecutionListener.class })
#WebAppConfiguration
public class MyControllerTest {
#Test
public void doTest() throws Exception {
mockMvc.perform(delete("/something/{i}", "123").with(user(new AppUser(...))));
}
#Configuration
public static class DummyAppConfig extends WebMvcConfigurerAdapter {
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new AuthenticationPrincipalArgumentResolver());
}
#Bean
public MyController aController() {
return new MyController();
}
}
#Configuration
#EnableWebSecurity
public static class DummySecurityConfiguration extends WebSecurityConfigurerAdapter {
}
```
And this is the full stacktrace:
```
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.corp.AppUser]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.corp.AppUser.<init>()
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:885)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:694)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:170)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:137)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:145)
at com.corp.ControllerTest.doTest(RestCorporateAccountSearchProfilesControllerTest.java:231)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:72)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:81)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:216)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:82)
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:60)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:67)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:162)
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.BeanInstantiationException: Could not instantiate bean class [com.corp.AppUser]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.corp.AppUser.<init>()
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:107)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:81)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:104)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:79)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:157)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:124)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
... 39 more
Caused by: java.lang.NoSuchMethodException: com.corp.AppUser.<init>()
at java.lang.Class.getConstructor0(Class.java:2800)
at java.lang.Class.getDeclaredConstructor(Class.java:2043)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:104)
... 52 more
```
If you use the MockMvcBuilders.standaloneSetup() method, you can add the resolver to the standalone MockMvc as so:
MockMvcBuilders.standaloneSetup(controller).setCustomArgumentResolvers(new AuthenticationPrincipalArgumentResolver()).build()
I too, had trouble getting it to work with the MockMvcBuilders.webAppContextSetup() method, but standalone worked without concern.
You need to use #EnableWebMvcSecurity on DummySecurityConfiguration in order to get the Spring Security / MVC integration. See http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#mvc-enablewebmvcsecurity

Spring 3.2 bean with constructor fails to initialize because of an injected property using #Required

In a Spring 3.2 project, I am bootstraping a service bean which has an injected property. The property is injected using #Required #Value(...) from a property file. I am sure the property file is being recognozed well by the spring context though.
Please check the service class below:
#Service
public class SomeService {
private String aURIString;
#Required
#Value("${someUrl}")
public void setaURIString(String aURIString) {
this.aURIString = aURIString;
}
private URI oamURI;
public SomeService() throws Exception {
super();
try {
oamURI = new URI(aURIString);
} catch (URISyntaxException e) {
throw new Exception("URISyntaxException created while creating a URI instance for url= "+aURIString);
}
}
}
Also please find the Configuration Class below
#Configuration
#EnableWebMvc
#PropertySource({ "classpath:filter.properties" })
#ComponentScan(basePackages = { "com.someOrg.SomePrj" })
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public static PropertySourcesPlaceholderConfigurer properties() {
return new PropertySourcesPlaceholderConfigurer();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
As well as the property file "filter.properties"
someUrl=http://www.google.com
When I test using the following test file
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(classes = {WebConfig.class})
public class RestTemplateTest {
#Resource
private SomeService someService;
#Test
public void testService() {
}
}
I get 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.TestContext.getApplicationContext(TestContext.java:122)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:105)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:74)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
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:174)
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: Error creating bean with name 'someService' defined in file [C:\CVS_Checkouts\someSpace\SomePrj\target\classes\com\someOrg\SomePrj\SomeService\SomeService.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.someOrg.SomePrj.SomeService.SomeService]: Constructor threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1013)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:959)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:128)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:248)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
... 25 more
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.someOrg.SomePrj.SomeService.SomeService]: Constructor threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1006)
... 41 more
Caused by: java.lang.NullPointerException
at java.net.URI$Parser.parse(Unknown Source)
at java.net.URI.<init>(Unknown Source)
at com.someOrg.SomePrj.SomeService.SomeService.<init>(SomeService.java:26)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
... 43 more
In the Service class, when I replace the line:
private String aURIString;
with the line
private String aURIString = "www.google.com"
it works fine though!
It, also, works fine and the #Required property is injected from the properties file if I empty the constructor and take the line:
oamURI = new URI(aURIString);
to a member method instead of the constructor
I need the #Required property in the constructor though!!!!!
Can somebody tell a means to make sure that the context injects the #Required property before calling the #Service class constructor, so it is available when the service constructor is called by the spring context?
There is no way to make value injected via setter available in constructor.
You can:
Use constructor injection instead:
#Autowired
public SomeService(#Value("${someUrl}") String aURIString) throws Exception { ... }
Use #PostConstruct instead of constructor for initialization code that depends on injected values:
#PostConstruct
public void init() throws Exception { ... }
Convert injected value in a setter instead of doing it in constructor:
#Required
#Value("${someUrl}")
public void setaURIString(String aURIString) throws Exception {
try {
oamURI = new URI(aURIString);
} catch (URISyntaxException e) {
throw new Exception("URISyntaxException created while creating a URI instance for url= "+aURIString);
}
}

Spring 3.2, jUnit 4.11, JPA NoSuchBeanDefinitionException: expected at least 1 bean

I am using annotation based spring configuration and trying to test my JPA based DAO. After configuration, when I ran the test, below error is thrown. I am out of any clue why the IPartnerDao is not found even though a Bean configuration is created in the Test class.
5173 [ERROR] org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener#3600e312] to prepare test instance [test.java.net.bornil.persistence.service.partner.PartnerDaoTest#148238f4]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'test.java.net.bornil.persistence.service.partner.PartnerDaoTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private main.java.net.bornil.persistence.service.IPartnerDao test.java.net.bornil.persistence.service.partner.PartnerDaoTest.parDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [main.java.net.bornil.persistence.service.IPartnerDao] 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:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1120)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:379)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:313)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
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:174)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
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:164)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private main.java.net.bornil.persistence.service.IPartnerDao test.java.net.bornil.persistence.service.partner.PartnerDaoTest.parDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [main.java.net.bornil.persistence.service.IPartnerDao] 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:514)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
... 32 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [main.java.net.bornil.persistence.service.IPartnerDao] 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:967)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:837)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:749)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
... 34 more
The test class
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = { JPAConfig.class })
public final class PartnerDaoTest {
#Configuration
static class ContextConfiguration {
#Bean
public IPartnerDao getParDao() {
return new PartnerDao();
}
}
#Autowired
private IPartnerDao parDao;
#Test
public void testFindPartnerWithAddress() throws Exception {
Partner partner = parDao.findPartnerWithAddress(1L);
assertNotNull(partner);
}
}
The DAO class
#Repository
#Transactional(readOnly = true)
public class PartnerDao implements IPartnerDao {
private static Logger logger = Logger.getLogger(PartnerDao.class.getName());
#PersistenceContext
private EntityManager em;
public PartnerDao() {
}
/* (non-Javadoc)
* #see main.java.net.bornil.persistence.service.IPartnerDao#find(java.lang.Long)
*/
#Override
public Partner findPartnerWithAddress(Long id) {
if (logger.isDebugEnabled()) {
logger.debug("Partner ID : " + id);
}
Query query = em.createQuery("select p from Partner p join fetch p.addressSet where p.id = :id");
query.setParameter("id", id);
return (Partner) query.getSingleResult();
}
}
The Partner interface
#Service
public interface IPartnerDao {
public Partner findPartnerWithAddress(Long id);
}
JPAConfig class
#Configuration
// #EnableLoadTimeWeaving
#EnableTransactionManagement
#PropertySource({ "classpath:jdbc.properties" })
public class JPAConfig {
#Autowired
Environment env;
#Bean
DataSource getJdbcDataSource() {
String jdbcUrl = env.getProperty("jdbc.url");
String username = env.getProperty("jdbc.username");
String password = env.getProperty("jdbc.password");
return new DriverManagerDataSource(jdbcUrl, username, password);
}
#Bean
public PlatformTransactionManager getTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(getEntityManagerFactoryBean().getObject());
return transactionManager;
}
#Bean
public LocalContainerEntityManagerFactoryBean getEntityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(getJdbcDataSource());
factory.setPackagesToScan(new String[] { "main.java.net.bornil.persistence.entity" });
HibernateJpaVendorAdapter hjva = new HibernateJpaVendorAdapter();
hjva.setGenerateDdl(false);
hjva.setShowSql(true);
hjva.setDatabasePlatform("org.hibernate.dialect.MySQLDialect");
factory.setJpaVendorAdapter(hjva);
return factory;
}
}
Make sure you have component scanning setup on your JPAConfig.class.
#ComponentScan("package.containing.PartnerDao")
public class JPAConfig{
}
Also try adding the test to the classes being loaded by the ContextLoader
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader = AnnotationConfigContextLoader.class,
classes = { JPAConfig.class, PartnerDaoTest.class })
public final class PartnerDaoTest {
/** tests**/
}

Running test with Spring. --> java.lang.IllegalStateException: Failed to load ApplicationContext

I'm having problems running a test case which returns java.lang.IllegalStateException: Failed to load ApplicationContext. I have already checked for the #ContextConfiguration but it looks right.
CLASSES:
public class MainSecurityInit extends SecurityFunctionalityCbosInit
{
protected FileWriter logFile = null;
private String logFileName = "";
/* _______________________ Initializers ________________________ */
#Autowired
private CbosSecurityInit cbosSecurityInit;
public void doTest()
{
Map<Class, Object> map = new HashMap<Class, Object>();
List<DataBaseInitializerResult> results = null;
initLogFile();
try
{
// -------------- Begin of initialization ------------------ //
cbosSecurityInit.execute();
// -------------- End of initialization -------------------- //
}
catch (Throwable ex)
{
logger.error(ex.getMessage());
ex.printStackTrace();
test(results);
}
finally
{
closeLogFile();
}
}
}
In the SecurityFunctionalityCbosInit the annotations are these:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = "security-functionality-cbos-context.xml")
#TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
#Transactional
public abstract class SecurityFunctionalityCbosInit extends AbstractTransactionalJUnit4SpringContextTests{
//
}
Stacktrace:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:203)
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:255)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:93)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:130)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
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: java.lang.IllegalStateException: Autowired annotation requires at least one argument: public void com.arcadia.security.MainSecurityInit.doTest()
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$2.doWith(AutowiredAnnotationBeanPostProcessor.java:307)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:466)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:443)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata(AutowiredAnnotationBeanPostProcessor.java:299)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(AutowiredAnnotationBeanPostProcessor.java:179)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:745)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:448)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:96)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:44)
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:173)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:199)
... 16 more
There is no setter for the property you are going to autowire (cbosSecurityInit). In stacktrace, there is a cause message: Autowired annotation requires at least one argument: public void.

Resources