使用服务组件运行时 [英] Using Service Component Runtime
问题描述
我的目标是从我的bundle中删除对OSGi的依赖。我使用felix(v 4.2.1)作为impl并运行它可嵌入。我安装 org.apache.felix.scr
(v.6.6.2)bundle以获得Service Component Runtime支持。但是当我运行时
I goal is to remove dependencies on OSGi from my bundles. I use felix (v 4.2.1) as impl and run it embeddable. I install org.apache.felix.scr
(v. 1.6.2) bundle to have Service Component Runtime support. But when I run
ServiceReference ref = bundleContext().getServiceReference(ScrService.class.getName());
ScrService s = (ScrService) bundleContext().getService(ref);
我得到 ClassCastException:org.apache.felix.scr.impl.ComponentRegistry无法转换为org.apache.felix.scr.ScrService
。
好的。我将修改系统包。
Okay. I will modify System Packages.
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
我该如何解决?
推荐答案
我怀疑你试图获得 ScrService
的第一个区块已开启嵌入方(即在框架之外,而不是在已安装的软件包中)。
I suspect your first block where you try to get hold of ScrService
is on the embedding side (i.e. outside of the framework, not from within an installed bundle).
如果是这种情况,那么你有两份 ScrService
- 一个从嵌入代码的ClassLoader加载,一个由scr b的ClassLoader加载当框架解决了它时。这就是为什么你看到 ClassCastException
。
If this is the case, then you have two copies of the ScrService
- one loaded from your embedding code's ClassLoader and one loaded by ClassLoader of the scr bundle when it's resolved by the framework. This is why you're seeing the ClassCastException
.
你可以从框架中导出SCR包的导出捆绑。
You can just export what the SCR bundle's exports from the framework bundle.
OSGi核心规范v5 指出,如果模块同时具有相同包的导入和导出定义,则在捆绑连接的解析中,框架将首先尝试从外部解析,如果成功丢弃重叠的导出定义。
Section 3.8, page 51 of the OSGi Core spec v5 states that in resolution of bundle wiring if a module has both import and export definitions of the same package then the framework will first try to resolve externally and if successful discard the overlapping export definition.
所以将SCR运行时包的Export-Package清单头复制为框架属性:
So copy the SCR runtime bundle's Export-Package manifest header as a framework property:
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 ,以确保您至少拥有<$ c $的API类c> org.osgi.service.cm。* 和org.osgi.service.metatype *
,AFAIK这些是SCR运行时所必需的。
If you're not already using
ConfigurationAdmin
, then also install org.osgi.compendium to ensure you have at least have the API classes fororg.osgi.service.cm.*
andorg.osgi.service.metatype*
, AFAIK these are necessary for the SCR runtime.
除非您认真定制实际框架,否则不应使用 Constants.FRAMEWORK_SYSTEMPACKAGES
您可能希望使用 Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA
来扩展框架包导出的内容。 (框架实现对于 FRAMEWORK_SYSTEMPACKAGES
具有非常好的默认值,并且在嵌入时通常不需要修改它。)
You shouldn't use Constants.FRAMEWORK_SYSTEMPACKAGES
unless you're seriously customising the actual framework, instead you'd probably want to use Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA
to extend what is exported by the framework bundle. (The framework implementations have pretty good defaults for FRAMEWORK_SYSTEMPACKAGES
and it's normally unnecessary to modify this when embedding).
这篇关于使用服务组件运行时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!