dschulten
dschulten

Reputation: 3122

Testing camel 2.24.x routes in Karaf 4.2.7 with CamelTestSupport

I want to test Camel 2.24.x routes in Karaf 4.2.x. I use Pax-Exam 4.13.1 to run Karaf. The Camel Testing Manual does not cover Karaf testing. For older Karaf and Camel versions there are blog articles which demonstrate how to do that by extending a test class from CamelTestSupport:

However, they are so old that the code no longer runs without adjustments. The former is pretty hopeless, I have stopped trying to fix it. For the latter I was able to get it to work on Karaf 2.4 with Camel 2.12.1 on JDK 8, but not with the current Karaf 4.2.7 using Camel 2.24.2.

With the current Karaf 4 and Camel 2.24 I get the following error message when CamelTestSupport tries to create a JndiContext in CamelTestSupport#createRegistry.

java.lang.ClassNotFoundException: org.apache.camel.util.jndi.CamelInitialContextFactory

    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at org.apache.felix.framework.BundleWiringImpl.doImplicitBootDelegation(BundleWiringImpl.java:1859)
    at org.apache.felix.framework.BundleWiringImpl.tryImplicitBootDelegation(BundleWiringImpl.java:1788)
    at org.apache.felix.framework.BundleWiringImpl.searchDynamicImports(BundleWiringImpl.java:1741)
    at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1617)
    at org.apache.felix.framework.BundleWiringImpl.access$200(BundleWiringImpl.java:80)
    at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2053)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:91)
    at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:61)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:672)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
    at javax.naming.InitialContext.init(InitialContext.java:244)
    at javax.naming.InitialContext.<init>(InitialContext.java:216)
    at org.apache.camel.test.junit4.CamelTestSupport.createJndiContext(CamelTestSupport.java:790)
    at org.apache.camel.test.junit4.CamelTestSupport.createRegistry(CamelTestSupport.java:776)
    at org.apache.camel.test.junit4.CamelTestSupport.createCamelContext(CamelTestSupport.java:770)
    at org.apache.camel.test.junit4.CamelTestSupport.doSetUp(CamelTestSupport.java:325)
    at org.apache.camel.test.junit4.CamelTestSupport.setUp(CamelTestSupport.java:265)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at 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.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
    at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)

The missing class is in camel-core and it used to be working with the older versions of Camel and Karaf, so I am at a loss why that class would not be available when using the latest Karaf and Camel.

What could be the reason why the CamelInitialContextFactory cannot be found? As in the older version, I install camel-blueprint and camel-test in my test, so I would expect that camel-core should be included.

Is it still a good idea to work with CamelTestSupport on Karaf? While there is a CamelKarafTestSupport which seems to demonstrate that approach, I could not find a working example for such a test and I could not get it to work myself either. With CamelKarafTestSupport I get an error telling me that ProbeInvoker never came up:

org.ops4j.pax.swissbox.tracker.ServiceLookupException: gave up waiting for service org.ops4j.pax.exam.ProbeInvoker

    at org.ops4j.pax.swissbox.tracker.ServiceLookup.getService(ServiceLookup.java:199)
    at org.ops4j.pax.swissbox.tracker.ServiceLookup.getService(ServiceLookup.java:136)
    at org.ops4j.pax.exam.rbc.internal.RemoteBundleContextImpl.remoteCall(RemoteBundleContextImpl.java:81)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:283)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:260)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:161)
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227)
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179)
    at com.sun.proxy.$Proxy15.remoteCall(Unknown Source)
    at org.ops4j.pax.exam.rbc.client.intern.RemoteBundleContextClientImpl$1.invoke(RemoteBundleContextClientImpl.java:102)
    at com.sun.proxy.$Proxy16.call(Unknown Source)
    at org.ops4j.pax.exam.rbc.client.intern.RemoteBundleContextClientImpl.call(RemoteBundleContextClientImpl.java:290)
    at org.ops4j.pax.exam.container.remote.RBCRemoteTarget.call(RBCRemoteTarget.java:60)
    at org.ops4j.pax.exam.karaf.container.internal.KarafTestContainer.call(KarafTestContainer.java:665)
    at org.ops4j.pax.exam.spi.reactors.EagerSingleStagedReactor.invoke(EagerSingleStagedReactor.java:109)
    at org.ops4j.pax.exam.junit.impl.ProbeRunner$2.evaluate(ProbeRunner.java:267)
    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.ops4j.pax.exam.junit.impl.ProbeRunner.run(ProbeRunner.java:98)
    at org.ops4j.pax.exam.junit.PaxExam.run(PaxExam.java:93)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Should I go a different route, maybe the AbstractFeatureTest from camel-test-karaf, which is used extensively by camel-itest-karaf?

Upvotes: 0

Views: 244

Answers (1)

dschulten
dschulten

Reputation: 3122

The advice in the pax-exam group was to use KarafTestSupport from org.apache.camel.itests:common for integration tests in pax-exam and stick to CamelTestSupport for unit tests. With that, I got the camel itests running again: https://github.com/dschulten/blog-camel-blueprint/tree/karaf4-paxexam4. In Karaf 4.2.7 KarafTestSupport requires numerous spring and activemq version system properties (see the configuration of the maven-surefire-plugin), that will go away as of Karaf 4.2.8. It is still possible to use camel mock routes in KarafTestSupport-based integration tests.

Upvotes: 0

Related Questions