【问题标题】:Registering services inside OSGi extension bundles在 OSGi 扩展包中注册服务
【发布时间】:2024-01-14 18:12:01
【问题描述】:

我正在使用 OSGi 框架扩展包以便完全理解它们。 在查看了 OSGi R6 规范 (3.15 and 4.2.4.1) 之后,我成功地调用了 ExtensionBundleActivator 的“开始”方法。现在我正在尝试在此类激活器中注册服务。但是,当我尝试使用此类服务​​时,引用注释无法连接该服务。

这是我的代码('已经更改了捆绑包的名称,但没关系):

public class ExtensionBundleActivator implements BundleActivator {

    @Override
    public void start(BundleContext context) throws Exception {
        System.out.println("start extension bundle activator!");

        context.registerService(
            BundleExample.class.getName(),
            new BundleExampleImpl(),
            new Hashtable<>(new HashMap<>()));
    }

    @Override
    public void stop(BundleContext context) throws Exception {
        //service automatically unregistered
    }

}

以下是此类扩展包的清单:

Manifest-Version: 1.0
Bnd-LastModified: 1476436248622
Build-Jdk: 1.8.0_91
Built-By: massi
Bundle-ClassPath: .
Bundle-ManifestVersion: 2
Bundle-Name: extensionbundleexample
Bundle-SymbolicName: com.massimobono.microsi.extensionbundleexample
Bundle-Version: 0.0.1.SNAPSHOT
Conditional-Package: com.massimobono.microsi.common.*;
Created-By: Apache Maven Bundle Plugin
ExtensionBundle-Activator: com.massimobono.microsi.bundleexample.imp
 l.ExtensionBundleActivator
Fragment-Host: system.bundle; extension:=framework
Provide-Capability: osgi.service;objectClass:List<String>="com.massimobo
 no.microsi.bundleexample.BundleExample"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Service-Component: OSGI-INF/com.massimobono.microsi.bundleexample.im
 pl.ExtensionBundleExample.xml
Tool: Bnd-3.0.0.201509101326

消费包(包的一部分):

@Reference(cardinality=ReferenceCardinality.OPTIONAL)
public BundleExample actualBundleExample;

@Activate
public void activate() {
    System.out.println("activating " + this.getClass().getSimpleName() + "with actual bundle set to "+ this.actualBundleExample);
}

我的问题是:我做错了什么?为什么消费者检测不到扩展包的注册服务?或者,也许我只是在做框架禁止的事情……在这种情况下,不可能从扩展包中提供服务吗?如何与扩展包中的代码进行交互(也就是访问扩展包本身的内容)?

这里有一些注意事项:

  1. 我使用 felix 作为 OSGi 实现;
  2. “ExtensionBundleExample”和“BundleExample”都加载到 felix 的自动进程文件夹中(默认是“bundle”,但我调整了 config.properties 以使用“corebundles”文件夹;
  3. 输出正确显示“启动扩展捆绑激活器!”但是当显示actualBundleExample的引用时,输出显示“null”;
  4. BundleExample 的可选基数用于测试目的:我只是想调用消费者组件具有的“激活器”方法(以便查看System.out.println 控制台;
  5. 从我之前的 question 中我了解到扩展包是 OSGi 框架中的一个小众市场,但我仍然想了解它们:我发现互联网上缺乏关于这个主题的示例非常烦人;

感谢您的回复!

【问题讨论】:

    标签: java osgi osgi-fragment


    【解决方案1】:

    扩展包的主要目的是用于框架扩展,绝对不是用于常规用途。 IE。扩展包通常与框架紧密耦合。原因是许多规则不计入扩展包,因为它们位于“错误”的一边。很少有例子有很好的理由。除非您真的知道自己在做什么,否则不应使用它们,因为大多数 OSGi 规则都不适用。

    就是这么说的。我的期望是您用于 BundleExample 的包在扩展包(来自类路径)和某些包导出的 DS 示例之间有所不同。由于它们来自不同的类加载器,OSGi 认为它们是不同的服务,因为当你尝试使用它时会遇到类加载器异常。

    你可以通过让框架导出这个包来解决这个问题。

    只是猜测。

    【讨论】:

    • 在 Felix config.properties 的条目“org.osgi.framework.system.packages.extra”中添加“com.massimobono.bundleexample”解决了这个问题。非常感谢! (顺便说一句,除此之外,我还不需要包含从框架中部署的包中提供“com.massimobono.bundleexample”的包......哦,好吧!)
    最近更新 更多