最近我写了一个使用Pax考试在Karaf容器中运行的集成测试,这是我的代码:
package com.mercury.mof.integration.tests;
import static org.ops4j.pax.exam.CoreOptions.maven;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.provision;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features;
import static org.ops4j.pax.tinybundles.core.TinyBundles.bundle;
import java.util.HashSet;
import java.util.Set;
import javax.inject.Inject;
import org.apache.karaf.features.Feature;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.OptionUtils;
import org.ops4j.pax.exam.ProbeBuilder;
import org.ops4j.pax.exam.TestProbeBuilder;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerMethod;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import com.mercury.mof.dataplatform.api.impl.DefaultMofDataPlatformModule;
import com.mercury.mof.foundation.framework.api.modular.IFramework;
import com.mercury.mof.foundation.framework.api.modular.IModule;
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerMethod.class)
public class FeaturesTest extends KarafTestSupport {
@ProbeBuilder
public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
probe.setHeader(
Constants.DYNAMICIMPORT_PACKAGE,
"*,org.apache.felix.service.*;status=provisional");
return probe;
}
//This is my custom service ,and when running tests Pax Exam always report ClassNotFoundException.
@Inject
IFramework framework;
@Override
@Configuration
public Option[] config() {
Option[] option = super.config();
// KarafFeatureDependencyGenerator generator = new
// KarafFeatureDependencyGenerator();
// System.out.println(maven().groupId(
// "org.apache.karaf.assemblies.features")
// .artifactId("standard").type("xml")
// .classifier("features")
// .versionAsInProject().getURL());
//
//
// try{
// System.out.println(
// generator.analysisFeature(System.getenv("m2_repo"), maven().groupId(
// "org.apache.karaf.assemblies.features")
// .artifactId("enterprise").type("xml")
// .classifier("features")
// .versionAsInProject().getURL()));
// }catch(Exception e){
// e.printStackTrace();
// }
Option[] combined = OptionUtils
.combine(
option,
features(
maven().groupId(
"org.apache.karaf.assemblies.features")
.artifactId("standard").type("xml")
.classifier("features")
.versionAsInProject(), "http",
"http-whiteboard"),
features(
maven().groupId(
"org.apache.karaf.assemblies.features")
.artifactId("enterprise").type("xml")
.classifier("features")
.versionAsInProject(), "transaction",
"jpa", "jndi"),
mavenBundle("org.osgi", "org.osgi.compendium", "4.2.0"),
mavenBundle("org.osgi", "org.osgi.core", "4.2.0"),
mavenBundle("org.osgi", "org.osgi.enterprise", "4.2.0"),
mavenBundle("com.mercury", "mof-foundation-commons",
"1.0.0.alpha"),
mavenBundle("com.mercury.mof",
"mof-foundation-framework-impl", "1.0.0.alpha"),
mavenBundle("com.mercury.mof",
"mof-foundation-cache-api", "1.0.0.alpha"),
mavenBundle("com.mercury.mof", "mof-data-platform-api",
"1.0.0.alpha"),
mavenBundle("com.mercury.mof",
"mof-data-platform-impl", "1.0.0.alpha"),
mavenBundle("com.mercury.mof",
"mof-foundation-framework-api", "1.0.0.alpha"),
mavenBundle("com.mercury.mof",
"mof-foundation-security-api", "1.0.0.alpha"),
mavenBundle("com.mercury.mof",
"mof-foundation-cache-api,1.0.0.alpha"),
mavenBundle("com.mercury.mof",
"mof-foundation-rbac-api", "1.0.0.alpha"),
provision(bundle()
.set("Import-Package",
"org.osgi.service.blueprint;version=\"[1.0.0,2.0.0)\",com.mercury.mof.foundation.framework.api.modular;version=\"[1.0,2)\",com.mercury.mof.dataplatform.api;version=\"[1.0,2)\",com.mercury.mof.foundation.commons.inf.lifecycle;version=\"[1.0,2)\",com.mercury.mof.foundation.framework.api.impl.modular;version=\"[1.0,2)\"")
.set("Export-Package",
"com.mercury.mof.dataplatform.api.impl;uses:=\"com.mercury .mof.foundation.framework.api.impl.modular,com.mercury.mof.foundation.c ommons.inf.lifecycle\";version=\"1.0.0.alpha\"")
.set("DynamicImport-Package", "*")
.set(Constants.BUNDLE_MANIFESTVERSION, "2")
.set(Constants.BUNDLE_SYMBOLICNAME,
"com.mercury.mof.mof-data-platform-impl-integration-test")
.set(Constants.BUNDLE_VERSION, "1.0.0.alpha")
.add(IFramework.class)
.add("OSGI-INF/blueprint/blueprint.xml",
getClass()
.getResource(
"/OSGI-INF/blueprint/blueprint.xml"))
.build())
);
return combined;
}
@Test
public void testTransactionFeature() throws Exception {
Assert.assertNotNull(this.featuresService);
assertFeatureInstalled("http");
assertFeatureInstalled("jpa");
assertFeatureInstalled("jndi");
assertFeatureInstalled("transaction");
Assert.assertNotNull(this.blueprintContainer);
Assert.assertNotNull(this.blueprintContainer.getComponentInstance("mofFrameworkServiceImpl"));
// Assert.assertNotNull(module);
}
protected Set<Feature> getFeatures(String features) throws Exception {
String[] featureArray = features.split("\\s");
Set<Feature> featureSet = new HashSet<Feature>();
for (String s : featureArray) {
if (s == null || (s = s.trim()).isEmpty()) {
continue;
}
Feature feature = this.featuresService.getFeature(s);
if (feature == null) {
throw new IllegalArgumentException("The feature which named:"
+ s + " can not be found.");
}
featureSet.add(feature);
}
return featureSet;
}
}
但我发现它无法通过测试,因为测试包无法找到我的自定义服务类(IFramework框架)并报告:
java.lang.ClassNotFoundException: com.mercury.mof.foundation.framework.api.modular.IFramework not found by PAXEXAM-PROBE-45604164-c35f-448b-9627-af8adb7e16f7 [110]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1460)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:72)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1843)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.getDeclaredFields0(Native Method)
at java.lang.Class.privateGetDeclaredFields(Class.java:2317)
at java.lang.Class.getDeclaredFields(Class.java:1762)
at org.junit.runners.model.TestClass.<init>(TestClass.java:49)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:75)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:57)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.<init>(ContainerTestRunner.java:53)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunnerBuilder.runnerForClass(ContainerTestRunnerBuilder.java:50)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunnerClassRequest.getRunner(ContainerTestRunnerClassRequest.java:61)
at org.junit.internal.requests.FilterRequest.getRunner(FilterRequest.java:31)
at org.junit.runner.JUnitCore.run(JUnitCore.java:138)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.invokeViaJUnit(JUnitProbeInvoker.java:123)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.findAndInvoke(JUnitProbeInvoker.java:96)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.call(JUnitProbeInvoker.java:72)
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:601)
at org.ops4j.pax.exam.rbc.internal.RemoteBundleContextImpl.remoteCall(RemoteBundleContextImpl.java:80)
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:601)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
我不知道问题出在哪里,实际上我在我的基础测试中注入了一些标准的osgi服务,它就像一个魅力,为什么当我使用自己的服务时它会导致麻烦?任何人都可以给我一些提示吗?非常感谢
答案 0 :(得分:1)
确保测试可以看到IFramework类的最佳方法是确保提供类的bundle安装在容器中。在@Configuration注释方法中使用mavenBundle是一个很好的方法。
您需要注意的事项: i)包含IFramework的包导出该类。 ii)如果您正在使用maven协调,请确保安装了人工制品(参见[1])。 iii)确保满足捆绑导出IFramework的依赖关系。
所以与您的代码相关的评论: i)您不需要安装osgi core,compendium&amp;企业(由karaf提供)。 ii)没有必要使用提供的东西来添加类和资源(我看到正在安装的类作为捆绑包和测试资源,无论如何都将可用。)
[1]:如果您的集成测试是与您在测试中使用的类相同的maven模块的一部分,则需要注意测试是在您的存储库中安装了artefact之前运行的,因此使用maven coords会导致问题。如果是这种情况,请考虑拆分测试,或不使用maven coords。