Refer spring context file from another project: JUnit & Spring - spring

I have a Spring MVC project(contains Controller & jsp files) and DAO project(Contains DB operation related files) & both the project are configured using annotations. MVC project depends on DAO project. Now, I am writing JUnit test for MVC and DAO projects. Hence I have created a separate 'Test project' in which I have added MVC project as dependency(Java Build Path -> Projects tab -> Add -> MVC Project & ok) and included all needed jar files (JUnit & spring-test.jar).
My project structure:
MVCProject (Depends on DAOProject --> Web App project)
|
WebContent
|
WEB-INF
|
spring-context.xml
DAOProject (Java project)
|
src
TestProject(Depends on MVCProject --> Java project)
|
src (packages)
|
JunitTestClass.java
Here is my test project code,
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"file:MVCProjectName/WebContent/WEB-INF/spring-context.xml"})
public class DAOImplTest {
#Autowired
private DAO dao;
String id = null;
/**
* Test method for {#link com.xyz.core.dao.DAOImpl#getById(java.lang.String)}.
*/
#Test
public void testGetById() {
id = "12345";
try {
dao.getById(id);
} catch (Exception e) {
e.printStackTrace();
}
}
}
I am getting 'File not found exception' as below.
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308)
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:220)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:301)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
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:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
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: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from URL [file:../../../../../../../RSPWebAPP/WebContent/WEB-INF/RoadSmartPro-servlet.xml]; nested exception is java.io.FileNotFoundException: MVCProjectName/WebContent/WEB-INF/spring-context.xml (The system cannot find the path specified.)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:341)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:81)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304)
... 24 more
Caused by: java.io.FileNotFoundException: MVCProjectName/WebContent/WEB-INF/spring-context.xml (The system cannot find the path specified.)
at java.io.FileInputStream.<init>(FileInputStream.java:149)
at java.io.FileInputStream.<init>(FileInputStream.java:108)
at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:103)
at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:201)
at org.springframework.core.io.UrlResource.getInputStream(UrlResource.java:124)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:328)
... 33 more
But, When I copy the spring-context.xml file from 'MVC project' into 'Test project' everything works fine. I copied the context file to following location in the test project and its working fine.
TestProject
|_
config(packageName)
|_
test-spring-context.xml
and its corresponding annotation
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:config/test-spring-context.xml"})
public class DAOImplTest {
.....
.....
}
But I don't want this approach since any change in the original context file(spring-context.xml) will not reflect in the copied file(test-spring-context.xml).
Is there a way to configure original context file in 'Test project'? Kindly suggest something.
Thanks in Advance.

Why dont you use the Maven Inheritence model? This is a good usecase for that since, you would want your tests to go along with your code. Also, any changes to the dependencies of the project would be handled using the Maven dependency management for you. I am assuming the two modules MVC Project and the DAOProject are packaged together.
Reference :
http://maven.apache.org/guides/introduction/introduction-to-the-pom.html#Project_Inheritance

Related

JUnit test case error: "Address already in use: bind"

I have a JUnit test case for my Project which is developed using
SpringBoot (1.3.5) & JDK 8. When I run my project as JUnit test in STS, all
test cases pass, but gives error at the end of each test cases, which
is: I am trying to run JUnit Coverage:
ERROR [ main] o.a.coyote.http11.Http11NioProtocol o.a.j.l.DirectJDKLog.log(DirectJDKLog.java:182) - |||||||||Failed to start end point associated with ProtocolHandler ["http-nio-8080"]
java.net.BindException: Address already in use: bind
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:340)
at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:773)
at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:473)
at org.apache.catalina.connector.Connector.startInternal(Connector.java:986)
........
........
........
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)
ERROR [ main] o.apache.catalina.core.StandardService o.a.j.l.DirectJDKLog.log(DirectJDKLog.java:182) - |||||||||Failed to start connector [Connector[HTTP/1.1-8080]]
org.apache.catalina.LifecycleException: Failed to start component [Connector[HTTP/1.1-8080]]
This error shows as the port 8080 is already in use. How to avoid this
error and let my all 20 test cases to run in one flow without this
error?
My code is:--->
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(KYCNotificationApplication.class)
#ActiveProfiles("local")
#WebIntegrationTest
#IntegrationTest({"server.port=0"})
public class DetermineKYCNotificationServiceImplTest {
#InjectMocks
DetermineKYCNotificationServiceImpl kycService;
#Mock
KYCOperationsDao kycOperationsDao;
#Mock
HttpServletRequest httpServletRequest;
#Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
...
}
#Test
public void testMeth1() {
try {
.....
assertTrue(......);
} catch (Exception e) {
e.printStackTrace();
}
}
#Test
public void testMeth2() {
try {
.....
assertTrue(......);
} catch (Exception e) {
e.printStackTrace();
}
}
...2o more test cases....
In Spring Boot < 1.4 you can annotate your test class with #IntegrationTest({"server.port=0"})
In Spring Boot >= 1.4 you can use #SpringBootTest(classes = Application.class , webEnvironment=WebEnvironment.RANDOM_PORT).
Both approaches have the same effect, namely; Spring will assign a random port (and will magically update the application properties in your test context to reflect this test-specific port).
More details in the docs ...
If you need to start a full running server for tests, we recommend that you use random ports. If you use #SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) an available port will be picked at random each time your test runs.
The #LocalServerPort annotation can be used to inject the actual port used into your test. For convenience, tests that need to make REST calls to the started server can additionally #Autowire a TestRestTemplate which will resolve relative links to the running server.
Update 1: based on your updated question I can now see that you are using #WebIntegrationTest. In this case you could simply add the randomPort parameter to that annotation e.g.
#WebIntegrationTest(randomPort = true)

How to make Weld lookup class on generated-sources

I have a maven project which i'm using MapStruct to generate mappers to help in the job of translating entities into DTOs and vice-versa.
This mappers are generated during the generate-sources phase of maven, and stored into target/generated-sources and target/AppName/WEB-INF/classes folders.
For example, I have this Mapper
#Mapper
public interface RuleMapper {
RuleDto ruletoDto(Rule rule);
//other cool stuf
}
I configurated MapStruct to use CDI, so it will generate the following:
#Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2016-12-19T23:19:36-0200",
comments = "version: 1.1.0.CR1, compiler: javac, environment: Java 1.8.0_112"
)
#Singleton
#Named
public class RuleMapperImpl implements RuleMapper {
#Override
public RuleDto ruletoDto(Rule rule) {
ruleDto ruleDto = new ruleDto();
if ( rule != null ) {
ruleDto.setIdRule( rule.getIdRule() );
}
return ruleDto;
}
}
It works perfectely when running on Wildfly server, the problem is that I'm trying to junit test this class, for this, I implemented a custom runner as shown bellow:
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
public class WeldJUnit4Runner extends BlockJUnit4ClassRunner {
public WeldJUnit4Runner(Class<Object> clazz) throws InitializationError {
super(clazz);
}
#Override
protected Object createTest() throws Exception {
final Class<?> test = getTestClass().getJavaClass();
return WeldContext.INSTANCE.getBean(test);
}
}
And:
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
public class WeldContext {
public static final WeldContext INSTANCE = new WeldContext();
private final Weld weld;
private final WeldContainer container;
private WeldContext() {
this.weld = new Weld();
this.container = weld.initialize();
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
weld.shutdown();
}
});
}
public <T> T getBean(Class<T> type) {
return container.instance().select(type).get();
}
}
These implementations were taken from here.
Finally, the test:
#RunWith(WeldJUnit4Runner.class)
public class RuleMapperTest {
#Inject
private RuleMapper ruleMapper;
#Test
public void coolTestName() {
Assert.assertTrue(Boolean.TRUE);
}
}
When I try to run, this is the console output:
log4j:WARN No appenders could be found for logger (org.jboss.logging).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
warning about logs, and the following exception:
java.lang.ExceptionInInitializerError
at br.com.treinoos.common.cdi.WeldJUnit4Runner.createTest(WeldJUnit4Runner.java:15)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
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.junit.runners.ParentRunner.run(ParentRunner.java:363)
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.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type RuleMapper with qualifiers #Default
at injection point [BackedAnnotatedField] #Inject private br.com.treinoos.model.core.business.treinoos.mappers.RuleMapperTest.ruleMapper
at br.com.treinoos.model.core.business.treinoos.mappers.RuleMapperTest.ruleMapper(RuleMapperTest.java:0)
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:63)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:56)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Like Weld wasn't abble to lookup the generated class.
The beans.xml is already created under src/test/resources/META-INF/beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
</beans>
Can anybody point me a solution to this problem? I've already searched something simillar, but no success.
Here's a full explanation to your problem and why what I wrote fixes it.
In Maven, you have at least 2 classloader. Your test classpath and your main classpath each have their own classloader. You can have others depending on your dependency structure. CDI identifies each classloader as a separate bean archive when running this way. src/main/webapp is explicitly for your WAR file. The beans.xml there does not give you a bean archive. Adding one to src/main/resources does. This problem is specific to how you're instantiating weld.
There are other projects that do this correctly - CDI-unit and Arquillian, specifically the Weld Embedded container. If you were to use one of these, this would not be an issue.

Pure JerseyTest without letting Spring messing with services

I am having hard time with JerseyTest and Spring. Previously in non-Spring Java projects what I usually did for my REST APIs was to extend my Test from JerseyTest, mocking the Service classes and simply (unit)testing my REST API. Now I'm using spring in my project where in my REST resource classes the Services are annotated with #Autowired. Now that I'm using the same scenario. Spring jumps in and nags about stuff like lack of applicationcontext.xml. I do want to use spring in my production but for my unit test I don't need my test know anything about Spring and all its autowiring and classpath annotation processing! How can I get this right? The classes look like this:
public class RESTResource{
#Autowired
MyService service;
#GET
public Response getSomeStuff(){
...
service.getStuff()
}
}
And here is the Test class
public class RESTResourceTest extends JerseyTest{
private Service service;
#Override
public Application configure(){
RESTResource resource = new RESTResource();
service = Mockito.mock(Service.class);
resource.setService(service);
ResourceConfig config = new ResourceConfig();
config.register(resource);
return config;
}
}
This is the stacktrace:
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext.xml]; nested exception is java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:344)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:217)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:252)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:127)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:93)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:538)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:452)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
at org.glassfish.jersey.server.spring.SpringComponentProvider.createXmlSpringConfiguration(SpringComponentProvider.java:173)
at org.glassfish.jersey.server.spring.SpringComponentProvider.createSpringContext(SpringComponentProvider.java:164)
at org.glassfish.jersey.server.spring.SpringComponentProvider.initialize(SpringComponentProvider.java:99)
at org.glassfish.jersey.server.ApplicationHandler$4.get(ApplicationHandler.java:408)
at org.glassfish.jersey.server.ApplicationHandler$4.get(ApplicationHandler.java:399)
at org.glassfish.jersey.internal.util.collection.Values$LazyValueImpl.get(Values.java:340)
at org.glassfish.jersey.server.ApplicationHandler$3.call(ApplicationHandler.java:350)
at org.glassfish.jersey.server.ApplicationHandler$3.call(ApplicationHandler.java:347)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:255)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:347)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:299)
at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer.<init>(InMemoryTestContainerFactory.java:77)
at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer.<init>(InMemoryTestContainerFactory.java:63)
at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory.create(InMemoryTestContainerFactory.java:111)
at org.glassfish.jersey.test.JerseyTest.createTestContainer(JerseyTest.java:277)
at org.glassfish.jersey.test.JerseyTest.setUp(JerseyTest.java:609)
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:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
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.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
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: java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:330)
... 56 more
P.S. I'm using spring boot.
What you can do is to simply exclude the jersey-spring3 using the the sure-fire plugin for test phase.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<classpathDependencyExcludes>
<classpathDependencyExclude>
org.glassfish.jersey.ext:jersey-spring3
</classpathDependencyExclude>
</classpathDependencyExcludes>
</configuration>
</plugin>
Here is some code snippets that might help in your case :
Option 1. Your REST resource class :
#Component
#Path("/api/helloworld")
public class RESTResource{
#Autowired
MyService service;
#GET
#Produces(MediaType.TEXT_PLAIN)
public String helloMessage() {
return "Hello World Jersey Way!";
}
}
Your test config class :
#Component
public class JerseyConfig extends ResourceConfig {
/**
* In constructor we can define Jersey Resources & Other Components
*/
public JerseyConfig() {
register(RESTResource.class);
}
}
3.Your test base class :
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)//NOTE : Application is a spring boot main class,or if you have specific configuration class similar to test config class above use #ContextConfiguration(classes = MyServiceSpringConfig.class)
public class RESTResourceTest extends JerseyTest {
#Override
protected Application configure() {
return new JerseyConfig();
}
#Test
public void contextLoads() {
}
#Test
public void someTest() throws Exception {
// Very useful test
}
}
Option 2 :
#Priority(value = 1)
public class MySpringWebInitializer implements WebApplicationInitializer
{
#Override
public void onStartup(ServletContext container)
{
//Tell jersey-spring3 the context is already initialized
container.setInitParameter("contextConfigLocation", "NOTNULL");
AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
appContext.register(RESTResource.class);
container.addListener(new ContextLoaderListener(appContext));
}
}
Also,for spring boot you can run test cases using an active profile or a config name ,pass runtime VM args with -Dspring.config.name=test for running test cases etc..
Hope this help and the rest is self explanatory.
The better way to integrate JerseyTest with Spring
No inheritance from JerseyTest in junit test class
No dependencies on Jersey in junit test class, just pure jax-rs dependency
perfectly integrate SpringJUnit4ClassRunner and #ContextConfiguration
My solution is hosted on github. Hope this help for you.

The XMLInputFactory does not recognize the property "reuse-instance" : Spring MVC, JUnit, RAD & Web sphere server

I have a Spring MVC project(contains Controller & jsp files) and DAO project(Contains DB operation related files) & both the project are configured using annotations. MVC project depends on DAO project. Now, I am writing JUnit test for MVC and DAO projects. Hence I have created a separate 'Test project' in which I have added MVC project as dependency(Java Build Path -> Projects tab -> Add -> MVC Project & ok) and included all needed jar files (JUnit & spring-test.jar). I am using RAD IDE, Spring 3, JUnit4 & Websphere application server (version 7).
My project structure:
MVCProject (Depends on DAOProject --> Web App project)
|
WebContent
|
WEB-INF
|
spring-context.xml
DAOProject (Java project)
|
src
TestProject(Depends on MVCProject --> Java project)
|
src
|
com.xyz.dao.test
|
DAOImplTest.java
|
config
|
test-spring-context.xml
I copied contents of spring-context.xml file into test-spring-context.xml.
Below is my JUnit test project code,
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:config/test-spring-context.xml"})
public class DAOImplTest {
#Autowired
private DAO dao;
String id = null;
/**
* Test method for {#link com.xyz.core.dao.DAOImpl#getById(java.lang.String)}.
*/
#Test
public void testGetById() {
id = "Test12345";
try {
dao.getById(id);
} catch (Exception e) {
e.printStackTrace();
}
}
}
I am getting following error when try to run test case (The XMLInputFactory does not recognize the property "reuse-instance").
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'imageHandler' defined in file [D:\Workspace\MVCProjectName\WebContent\WEB-INF\classes\com\xyz\web\webservice\ImageHandlerImpl.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.xyz.webservice.ImageHandlerImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: The XMLInputFactory does not recognize the property "reuse-instance".
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:965)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:911)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:435)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:409)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:541)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:147)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:297)
... 64 more
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.xyz.webservice.ImageHandlerImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: The XMLInputFactory does not recognize the property "reuse-instance".
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:141)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:74)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:958)
... 77 more
Caused by: java.lang.IllegalArgumentException: The XMLInputFactory does not recognize the property "reuse-instance".
at com.ibm.xml.xlxp.api.stax.msg.StAXMessageProvider.throwIllegalArgumentException(StAXMessageProvider.java:42)
at com.ibm.xml.xlxp.api.stax.XMLInputFactoryImpl.setProperty(XMLInputFactoryImpl.java:1870)
at org.apache.axiom.util.stax.dialect.SJSXPDialect.makeThreadSafe(SJSXPDialect.java:65)
at org.apache.axiom.om.util.StAXUtils$8.run(StAXUtils.java:544)
at java.security.AccessController.doPrivileged(AccessController.java:229)
at org.apache.axiom.om.util.StAXUtils.newXMLInputFactory(StAXUtils.java:517)
at org.apache.axiom.om.util.StAXUtils.getXMLInputFactory_perClassLoader(StAXUtils.java:588)
at org.apache.axiom.om.util.StAXUtils.getXMLInputFactory(StAXUtils.java:171)
at org.apache.axiom.om.util.StAXUtils.getXMLInputFactory(StAXUtils.java:136)
at org.apache.axiom.om.util.StAXUtils.createXMLStreamReader(StAXUtils.java:223)
at org.apache.axiom.om.util.StAXUtils.createXMLStreamReader(StAXUtils.java:217)
at org.apache.axis2.util.XMLUtils.toOM(XMLUtils.java:555)
at org.apache.axis2.deployment.DescriptionBuilder.buildOM(DescriptionBuilder.java:93)
at org.apache.axis2.deployment.AxisConfigBuilder.populateConfig(AxisConfigBuilder.java:76)
at org.apache.axis2.deployment.DeploymentEngine.populateAxisConfiguration(DeploymentEngine.java:640)
at org.apache.axis2.deployment.FileSystemConfigurator.getAxisConfiguration(FileSystemConfigurator.java:105)
at org.apache.axis2.context.ConfigurationContextFactory.createConfigurationContext(ConfigurationContextFactory.java:60)
at org.apache.axis2.context.ConfigurationContextFactory.createConfigurationContextFromFileSystem(ConfigurationContextFactory.java:174)
at org.apache.axis2.jaxws.ClientConfigurationFactory.getClientConfigurationContext(ClientConfigurationFactory.java:51)
at org.apache.axis2.jaxws.description.impl.DescriptionFactoryImpl.createServiceDescription(DescriptionFactoryImpl.java:74)
at org.apache.axis2.jaxws.description.DescriptionFactory.createServiceDescription(DescriptionFactory.java:67)
at org.apache.axis2.jaxws.spi.ServiceDelegate.<init>(ServiceDelegate.java:84)
at org.apache.axis2.jaxws.spi.Provider.createServiceDelegate(Provider.java:45)
at javax.xml.ws.Service.<init>(Service.java:57)
at com.xyz.handler.broker.ImageHandlerService.<init>(ImageHandlerService.java:39)
at com.xyz.handler.broker.ImageHandlerProxy$Descriptor.<init>(ImageHandlerProxy.java:21)
at com.xyz.handler.broker.ImageHandlerProxy.<init>(ImageHandlerProxy.java:69)
at com.xyz.webservice.ImageHandlerImpl.<init>(ImageHandlerImpl.java:30)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:80)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:57)
at java.lang.reflect.Constructor.newInstance(Constructor.java:539)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126)
... 79 more
Kindly help me resolving this issue.
Thanks in Advance.
Folks,
I am able to resolve the issue.
This problem occurs when my RAD JRE System library set to jdk7 and so it is resolved by setting RAD 'JRE System library' to 'JavaSE-1.6' (Properties --> Libraries tab --> JRE System library --> Click edit & set JavaSE-1.6).
The reason might be jar conflict between sun jdk7, IBM(xml.jar) and apache axiom versions (Not sure but as far as I googled ended up with this assumption).
Hope it helps someone facing similar issue.
Happy learning.
This is an issue in Axiom that has been fixed in 1.2.15. See AXIOM-443 for more details.

Failed to load ApplicationContext for JUnit test of Spring controller

I want to write a test case to check my controller (getPersons). This is a server side code. I have confusion what should i put inside #ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/app-contest.xml"})
Secondly, I'm getting some errors like this:
Failed to load application context. Can not find the path [which I specified in #ContextConfiguration]
I have a structure like this:
restAPI
*src/main/java
com.company.controller
personController.java
*Test
com.company.testController
personControllerTest.java
*src
main
webapp
WEBINF
app-context.xml
#Autowired
private PersonService personService;
#RequestMapping(value="/t2/{yy_id}/person", method=RequestMethod.GET)
#ResponseBody
public PersonInfo[] getPersons() {
return personService.getPersons();
}
This is my Test
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"classpath:WEB-INF/app-context.xml"})
#WebAppConfiguration
public class PersonControllerTest {
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
#Autowired
private PersonService personService;
#Test
public void getPersons() throws Exception {
this.mockMvc.perform(get("/t2/1/person")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
Trace
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:103)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:73)
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.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.BeanDefinitionStoreException: IOException parsing XML document from class path resource [WEB-INF/application-context.xml]; nested exception is java.io.FileNotFoundException: class path resource [WEB-INF/application-context.xml] cannot be opened because it does not exist
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:341)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:243)
at org.springframework.test.context.web.GenericXmlWebContextLoader.loadBeanDefinitions(GenericXmlWebContextLoader.java:38)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:113)
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:248)
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:124)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148)
... 24 more
Caused by: java.io.FileNotFoundException: class path resource [WEB-INF/app-context.xml] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:157)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:328)
Can some one please help me out to figure it out what's wrong here?
As mentioned in the discussion: WEB-INF is not really part of the class path. If you use a common template, such as maven, use src/main/resources or src/test/resources to place the app-context.xml in. Then you can use classpath:.
Place your config file in src/main/resources/app-context.xml and use the following code:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = "classpath:app-context.xml")
public class PersonControllerTest {
...
}
You can also create your test context with different configurations of beans.
Place your config file into src/test/resources/test-app-context.xml and use:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = "classpath:test-app-context.xml")
public class PersonControllerTest {
...
}
There can be multiple root causes for this exception. For me, my mockMvc wasn't getting auto-configured. I solved this exception by using #WebMvcTest(MyController.class) at the class level. This annotation will disable full auto-configuration and instead apply only configuration relevant to MVC tests.
An alternative to this is, If you are looking to load your full application configuration and use MockMVC, you should consider #SpringBootTest combined with #AutoConfigureMockMvc rather than #WebMvcTest
If you are using Maven, add the below config in your pom.xml:
<build>
<testResources>
<testResource>
<directory>src/main/webapp</directory>
</testResource>
</testResources>
</build>
With this config, you will be able to access xml files in WEB-INF folder.
From Maven POM Reference:
The testResources element block contains testResource elements. Their definitions are similar to resource elements, but are naturally used during test phases.
In case you landed here based on the title, desperate for a solution and happen to be using Junit 5 Jupiter, you need to use
#ExtendWith(SpringExtension.class)
instead of
#RunWith(SpringJUnit4ClassRunner.class)
Try this with Junit5:
#SpringBootTest(classes = {ServletWebServerFactoryAutoConfiguration.class},
webEnvironment = RANDOM_PORT,
properties = {"spring.cloud.config.enabled=false"})
#ExtendWith(MockitoExtension.class)
#AutoConfigureMockMvc
Using same version of spring boot and spring cloud dependency works for me.
Sovled by editing the annotation
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
Solved by adding the following dependency into pom.xml file :
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>

Resources