简体   繁体   English

使用嵌入式OSGi容器

[英]Using an embedded OSGi container

I am building some modules which I want to expose as OSGi bundles without any actual dependencies to OSGi libraries. 我正在构建一些我希望作为OSGi包公开的模块,而没有任何与OSGi库的实际依赖关系。 It would seem that this is possible using the declarative services option. 看来这可能是使用声明性服务选项。

However because I'm rather new to OSGi (at least on the bundle-creating side) I want to test if it all works as it should, to this end I want to set up a small embedded OSGi environment. 但是因为我对OSGi很新(至少在创建捆绑包方面)我想测试它是否一切正常,为此我想建立一个小的嵌入式OSGi环境。

Currently I have a single bundle which exports an API and also provides a stub implementation of a single interface. 目前我有一个导出API的bundle,还提供了单个接口的stub实现。

I have followed the following tutorials to set up an environment: 我按照以下教程设置了一个环境:

And the embedded felix implementation seems to work properly however there are two problems: 嵌入式felix实现似乎正常工作,但有两个问题:

Bundle bundle = felix.getBundleContext().installBundle("/path/to/bundle.jar")
bundle.start();
System.out.println(bundle.getRegisteredServices());

This prints out null so while the bundle is seemingly started ok, it does not seem to expose any services. 这打印出null所以当捆绑看起来好了,它似乎没有公开任何服务。

Secondly I'm wondering whether I have to do anything special to get the declarative services bit up and running. 其次,我想知道是否必须做一些特殊的事情才能使声明性服务更新并运行。 My maven dependencies are: 我的maven依赖是:

<dependencies>
    <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.framework</artifactId>
        <version>4.2.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.scr</artifactId>
        <version>1.6.2</version>
    </dependency>
</dependencies>

Based on the email thread found here: http://mail-archives.apache.org/mod_mbox/felix-users/201111.mbox/%3CAE48C9B8172EFC48A028B60E8D6F96660143A5F336@sausexmbp02.amd.com%3E 基于此处的电子邮件主题: http//mail-archives.apache.org/mod_mbox/felix-users/201111.mbox/%3CAE48C9B8172EFC48A028B60E8D6F96660143A5F336@sausexmbp02.amd.com%3E

I tried to add the bundle to the felix startup properties: 我试图将包添加到felix启动属性:

map.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "org.apache.felix.scr; version=1.6.2");

However this seems a bit optimistic at first glance. 然而,乍一看这似乎有点乐观。 How do I enable the declarative services for an embedded felix engine? 如何为嵌入式felix引擎启用声明性服务?

The solution to both problems was to load the "scr" jar (used to parse declarative services) as a bundle before loading my own bundles. 这两个问题的解决方案是在加载我自己的bundle之前加载“scr”jar(用于解析声明性服务)作为bundle。

Because the jar is located in my maven repository and it should work cross system, the following bit of code loads the scr jar from wherever it resides: 因为jar位于我的maven存储库中并且它应该跨系统工作,所以下面的一些代码从它所在的任何地方加载scr jar:

    URL url = getClass().getClassLoader().getResource("org/apache/felix/scr/ScrService.class");
    String jarPath = url.toURI().getSchemeSpecificPart().replaceAll("!.*", "");
    framework.getBundleContext().installBundle(jarPath).start();

After this bit I load my own bundle and the services in it were detected properly. 在这一点之后,我加载了我自己的包,并正确检测到其中的服务。

On a sidenote, you can enable logging by adding some properties to the initial map: 在旁注中,您可以通过向初始映射添加一些属性来启用日志记录:

    map.put("ds.showtrace", "true");
    map.put("ds.showerrors", "true");

More properties can be found at http://felix.apache.org/documentation/subprojects/apache-felix-service-component-runtime.html 更多属性可以在http://felix.apache.org/documentation/subprojects/apache-felix-service-component-runtime.html找到。

For future reference, here is all the code I used to get it up and running 为了将来参考,这里是我用来启动和运行的所有代码

private void initialize() throws BundleException, URISyntaxException {
    Map<String, String> map = new HashMap<String, String>();

    // make sure the cache is cleaned
    map.put(Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);

    // more properties available at: http://felix.apache.org/documentation/subprojects/apache-felix-service-component-runtime.html
    map.put("ds.showtrace", "true");
    map.put("ds.showerrors", "true");

    System.out.println("Building OSGi Framework");
    FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next();
    Framework framework = frameworkFactory.newFramework(map);

    System.out.println("Starting OSGi Framework");
    framework.start();

    // declarative services dependency is necessary, otherwise they won't be picked up!
    loadScrBundle(framework);

    framework.getBundleContext().installBundle("file:/path/to/myBundle.jar").start();

    ServiceReference reference = framework.getBundleContext().getServiceReference("my.Interface");
    System.out.println(framework.getBundleContext().getService(reference));

    for (Bundle bundle : framework.getBundleContext().getBundles()) {
        System.out.println("Bundle: " + bundle.getSymbolicName());
        if (bundle.getRegisteredServices() != null) {
            for (ServiceReference serviceReference : bundle.getRegisteredServices())
                System.out.println("\tRegistered service: " + serviceReference);
        }
    }
}

private void loadScrBundle(Framework framework) throws URISyntaxException, BundleException {
    URL url = getClass().getClassLoader().getResource("org/apache/felix/scr/ScrService.class");
    if (url == null)
        throw new RuntimeException("Could not find the class org.apache.felix.scr.ScrService");
    String jarPath = url.toURI().getSchemeSpecificPart().replaceAll("!.*", "");
    System.out.println("Found declarative services implementation: " + jarPath);
    framework.getBundleContext().installBundle(jarPath).start();
}

I suggest to take a look at pax exam . 我建议看一下pax考试 It allows to test your bundle in an OSGi container. 它允许在OSGi容器中测试您的包。 The nice thing is that it integrates with junit so your test look very similar to normal tests.For some examples see the Apache Karaf Tests . 好处是它与junit集成,因此您的测试看起来非常类似于普通测试 。有些示例请参阅Apache Karaf测试

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM