0

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.

рüффп
  • 5,172
  • 34
  • 67
  • 113
Ashish
  • 1,121
  • 2
  • 15
  • 25
  • There is most likely more to the stacktrace than you've provided. Typically you'd get 'Failed to Load Application Context' followed by the actual Exception that called. – Sheena Artrip Jan 03 '14 at 23:02

2 Answers2

1

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.

Sheena Artrip
  • 1,990
  • 12
  • 16
  • I see what you are saying. But the problem is I cant get rid off osgi:reference because at some point in my program I invoke one of the methods exposed by osgi:service. which leads to my next question which is How can I write a JUNIT test case to test OSGI service. Thankx for your suggestion. – Ashish Jan 03 '14 at 23:29
  • You have to get rid of the OSGI reference. If you can't, add OSGI to your unit test OR follow my instructions above. Using profiles OR a separate spring context, you can provide a mock or non-OSGI version of the service as a bean. – Sheena Artrip Jan 04 '14 at 01:01
1

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.

Achim Nierbeck
  • 5,265
  • 2
  • 14
  • 22
  • so based on your suggestion I was looking into https://ops4j1.jira.com/wiki/display/PAXEXAM3/Getting+Started+with+OSGi+Tests .. I was able to find the maven setup to run tests. Now I am having difficulty understanding ho to return 'Options[]'. I am confused because all I am trying to invoke is an OSGI service and I do not know how to set that up in config() method. Do u have any sample of this which I could follow to write a simple JUNIT test case to test an OSGI service. Thanks a lot for your input. – Ashish Jan 05 '14 at 15:42
  • For testing services you'll need to setup a OSGi environment. If you take a look at the given blog post it'll explain how to setup an testing environment for Camel with Karaf as container, the sources can be found at github. – Achim Nierbeck Jan 05 '14 at 19:39