3

最近我写了一个在 Karaf 容器中运行的集成测试,它使用 Pax Exam,这是我的代码:

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 服务,它就像一个魅力,为什么在我使用自己的服务时会导致麻烦?有人可以给我一些提示吗?非常感谢

4

1 回答 1

1

确保您的测试可以看到 IFramework 类的最佳方法是确保提供该类的包已安装在您的容器中。在 @Configuration 注解的方法中使用 mavenBundle 是一个不错的方法。

您需要注意的事项: i) 包含 IFramework 的包导出类。ii) 如果您使用 maven 协调,请确保已安装人工制品(请参阅 [1])。iii) 确保满足捆绑导出 IFramework 的依赖关系。

所以与您的代码相关的评论:i)您不需要安装 osgi 核心、纲要和企业(它们由 karaf 提供)。ii) 无需使用提供的东西来添加类和资源(我看到作为捆绑包安装的类和测试资源无论如何都将可用)。

[1]:如果您的集成测试是与您在测试中使用的类相同的 maven 模块的一部分,您需要注意测试是在工件安装到您的存储库之前运行的,因此使用 maven 坐标可以导致到问题。如果是这种情况,请考虑拆分测试,或者不要使用 maven 坐标。

于 2013-12-02T10:44:51.900 回答