Failed to load ApplicationContext while running JUNIT test case

1.6k views Asked by At

I have an OSGI Bundle (B) deployed in ServiceMix Container. B also acts as an OSGI Endpoint. As we can see the following line (from my ApplicationContext.xml)

<osgi:service id="SampleManagementService" ref="ManagementService" interface="com.abc.webservice.xyz.ISampleManagementService"/>

Now, I have another Bundle (C) deployed inside the same servicemix container and C wants to consume OSGI service exposed from B. So I added the following line in the applicationContext of Bundle C.

<osgi:reference id="SampleManagementService" interface="com.abc.webservice.xyz.ISampleManagementService"/>

So far so good. Now I wrote a JUNIT test case in Bundle C which tries to load its applicationContext.xml before executing the test case. Here is a snippet of my test class:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/META-INF/spring/camel-context.xml"})
public class TimerTest {
   //some logic to execute the test.
}

whenever I try to run this unit test case, I get java.lang.IllegalStateException:. which is too generic to give me any clue about the issue.

Here is the stack trace of the exception I am seeing in my console:

main] TestContextManager ERROR Caught exception while allowing        TestExecutionListener        [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@1526ea43] to prepare test instance [com.abc.sms.webservice.test.TimerTest@2ddddf8e]
java.lang.IllegalStateException: Failed to load ApplicationContext
at   org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308) [spring-test-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at  org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)[spring-test-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)[spring-test-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)[spring-test-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:220)[spring-test-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:301)[spring-test-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)[junit-4.7.jar:]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303)[spring-test-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)[spring-test-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)[junit-4.7.jar:]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)[junit-4.7.jar:]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)[junit-4.7.jar:]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)[junit-4.7.jar:]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)[junit-4.7.jar:]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)[junit-4.7.jar:]
at  org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)[spring-test-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)[spring-test-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)[junit-4.7.jar:]
at  org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)[spring-test-3.0.5.RELEASE.jar:3.0.5.RELEASE]

I am not exactly sure whats causing the issue. I tried removing the JARS from POM.xml but that dint help either. I also looked for similar questions in Stackoverflow but most of them answers with changing the classpath of Application-Context.xml in my test class which is not my case for sure. As soon as I remove <osgi:reference> from Bundle C, My test runs successfully.

Any suggestion would help. Thanks.

2

There are 2 answers

2
Achim Nierbeck On

There is this project called Pax Exam to be used for JUnit inside OSGi containers. As ServiceMix is based on Top of Karaf you might be interested in knowing that Pax Exam also supports a Karaf Container as runtime (since version 3.4). You'll find more details on how to use Pax Exam at OPS4j. You might also be interested in how to test Camel OSGi, there is a blog post at Testing Camel JPA Routes. Even though the blog post uses Blueprint, it easily could be transferred to spring.

2
Sheena Artrip On

If you have an OSGI Service Reference (which you do because you are using the osgi:reference spring tag), you need that reference when you evaluate your unit test. Since the unit test you are running has no OSGI runtime, that osgi:reference is failing.

Your best bet is to write your unit test with an alternate version of /META-INF/spring/camel-context.xml that does not try to use the OSGI runtime.

Without knowing which version of spring you are on, profiles in 3.1 can also help.