【问题标题】:Using Service Component Runtime使用服务组件运行时
【发布时间】:2013-04-15 13:49:28
【问题描述】:

我的目标是从我的包中移除对 OSGi 的依赖。我使用 felix (v 4.2.1) 作为 impl 并运行它可嵌入的。我安装 org.apache.felix.scr (v. 1.6.2) 捆绑包以获得服务组件运行时支持。但是当我运行时

 ServiceReference ref = bundleContext().getServiceReference(ScrService.class.getName());
 ScrService s = (ScrService) bundleContext().getService(ref);

我收到ClassCastException: org.apache.felix.scr.impl.ComponentRegistry cannot be cast to org.apache.felix.scr.ScrService。

好的。我会修改系统包。

config.put(Constants.FRAMEWORK_SYSTEMPACKAGES, "org.apache.felix.scr");

现在我明白了

Caused by: org.osgi.framework.BundleException: Unresolved constraint in bundle org.apache.felix.scr [1]: Unable to resolve 1.0: missing requirement [1.0] osgi.wiring.package; (&(osgi.wiring.package=org.osgi.framework)(version>=1.4.0)(!(version>=2.0.0)))
        at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:3974)
        at org.apache.felix.framework.Felix.startBundle(Felix.java:2037)
        at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:955)
        at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:942)
        at com.copyright.rup.communications.felix.Felix.addBundle(Felix.java:86)
        ... 28 more

我该如何解决?

【问题讨论】:

    标签: java osgi apache-felix


    【解决方案1】:

    我怀疑您尝试获取ScrService 的第一个块位于嵌入端(即在框架之外,而不是在已安装的捆绑包中)。

    如果是这种情况,那么您有两个 ScrService 副本 - 一个从嵌入代码的 ClassLoader 加载,另一个在框架解析时由 scr 包的 ClassLoader 加载。这就是您看到ClassCastException 的原因。

    您可以只从框架包中导出 SCR 包的导出内容。

    OSGi Core spec v5 的第 51 页第 3.8 节指出,如果模块同时具有相同包的导入和导出定义,则框架将首先尝试在外部解析,如果成功则丢弃重叠的导出定义.

    因此,将 SCR 运行时包的 Export-Package 清单标头复制为框架属性:

    properties.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, 
            "org.ops4j.pax.url.mvn,org.apache.felix.scr;uses:=\"org.osgi.framework," +
            "org.osgi.service.component\";version=\"1.7\"," +
            "org.apache.felix.scr.component;status=provisional;mandatory:=status;" +
            "uses:=\"org.osgi.service.component\";version=\"1.0\"," +
            "org.osgi.service.component;uses:=\"org.osgi.framework\";version=\"1.2\"");
    
    //Which you pass to the FrameworkFactory ...
    
    ServiceLoader<FrameworkFactory> loader = ServiceLoader.load(FrameworkFactory.class);
    Iterator<FrameworkFactory> iterator = loader.iterator();
    Framework framework = iterator.next().newFramework(properties);
    framework.start();
    

    有几点需要注意:

    • 如果您还没有使用ConfigurationAdmin,那么还要安装org.osgi.compendium 以确保您至少拥有org.osgi.service.cm.* 和org.osgi.service.metatype* 的API 类,AFAIK 这些是SCR 运行时所必需的.

    • 除非您认真定制实际框架,否则不应使用 Constants.FRAMEWORK_SYSTEMPACKAGES,相反,您可能希望使用 Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA 来扩展框架导出的内容捆。 (框架实现对FRAMEWORK_SYSTEMPACKAGES 有很好的默认值,嵌入时通常不需要修改它。

    【讨论】:

    • 为了更清楚地说明问题第二部分中导致分辨率错误的原因...通过使用 FRAMEWORK_SYSTEMPACKAGES,他删除了 ALL 系统捆绑包导出,除了org.apache.felix.scr。所以,再见org.osgi.framework...再见javax.*...你明白了。使用 FRAMEWORK_SYSTEMPACKAGES_EXTRA 应该修复它。
    • 谢谢。你帮了我很多。
    猜你喜欢
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 2019-07-09
    相关资源
    最近更新 更多