【问题标题】:Using an embedded OSGi container使用嵌入式 OSGi 容器
【发布时间】:2013-05-18 10:48:26
【问题描述】:

我正在构建一些模块,我想将它们公开为 OSGi 捆绑包,而不需要对 OSGi 库有任何实际依赖关系。使用声明式服务选项似乎可以做到这一点。

但是,由于我对 OSGi 比较陌生(至少在创建包方面)我想测试它是否一切正常,为此我想建立一个小型嵌入式 OSGi 环境。

目前我有一个单独的包,它导出一个 API 并提供一个单一接口的存根实现。

我已按照以下教程设置环境:

嵌入的 felix 实现似乎工作正常,但是有两个问题:

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

这会打印出null,因此虽然捆绑包似乎启动正常,但它似乎没有公开任何服务。

其次,我想知道我是否必须做一些特别的事情来让声明式服务启动并运行。我的 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>

基于此处找到的电子邮件线程:http://mail-archives.apache.org/mod_mbox/felix-users/201111.mbox/%3CAE48C9B8172EFC48A028B60E8D6F96660143A5F336@sausexmbp02.amd.com%3E

我尝试将捆绑包添加到 felix 启动属性:

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

不过,乍一看,这似乎有点乐观。如何为嵌入式 felix 引擎启用声明式服务?

【问题讨论】:

    标签: java osgi apache-felix


    【解决方案1】:

    我建议看看pax exam。它允许在 OSGi 容器中测试你的包。 好处是它与 junit 集成,因此您的测试看起来与普通测试非常相似。有关示例,请参阅 Apache Karaf Tests

    【讨论】:

      【解决方案2】:

      解决这两个问题的方法是在加载我自己的包之前将“scr”jar(用于解析声明性服务)作为包加载。

      因为 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();
      

      在此之后,我加载了自己的包,并且正确检测到其中的服务。

      在旁注中,您可以通过向初始地图添加一些属性来启用日志记录:

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

      更多房源请访问http://felix.apache.org/documentation/subprojects/apache-felix-service-component-runtime.html

      为了将来参考,这里是我用来启动和运行它的所有代码

      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();
      }
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-02
      • 2012-05-13
      • 1970-01-01
      • 2010-10-04
      • 2018-10-05
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      相关资源
      最近更新 更多