使用服务组件运行时

时间:2013-04-22 15:27:28

标签: java osgi apache-felix

我的目标是从我的bundle中删除对OSGi的依赖。我使用felix(v 4.2.1)作为impl并运行它可嵌入。我安装了org.apache.felix.scr(v.1.6.2)软件包以获得Service Component Runtime支持。但是当我跑步时

 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

我该如何解决?

1 个答案:

答案 0 :(得分:4)

我怀疑你试图抓住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类,这些是SCR运行时必需的AFAIK。

  • 除非您认真定制实际框架,否则不应使用Constants.FRAMEWORK_SYSTEMPACKAGES,而是您可能希望使用Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA 扩展什么是由框架包导出。 (框架实现具有非常好的FRAMEWORK_SYSTEMPACKAGES默认值,并且在嵌入时通常不需要修改它。