如何创建具有可选包解析的工作 OSGi 包?

How to create a working OSGi bundle with optional package resolution?

我希望我的 bundle 可以通过系统属性或 OSGi Compendium Config Admin 进行配置。

我正在根据 org.osgi:osgi.cmpn:6.0.0 包编译我的包,因为 made clear in the OSGi Alliance blog 仅在编译时使用,框架在运行时提供实际实现。

我的代码显然需要使用 ConfigAdmin 包(以处理存在 ConfigAdmin 服务的情况)...这意味着如果运行时不导出 ConfigAdmin 包,我的包将无法正确解析。

但我希望此解决方案是可选的...所以我将其添加到清单中:

org.osgi.service.cm;resolution:=optional;version="[1.5,2)"

现在,即使用户实际上不会使用 ConfigAdmin 进行配置,捆绑包也会解析,但会在运行时崩溃并显示 java.lang.NoClassDefFoundError: org/osgi/service/cm/ManagedService。因此,这会强制用户安装 config-admin 包,以使我的包正常工作。

我想这里的秘诀是不实例化任何 class 强制 JVM 加载使用 org.osgi.service.cm 包的 class 的 es...但我不能看看我如何在没有反射的丑陋黑客的情况下实现这一目标...

有谁知道我如何检查包在运行时是否可用,如果不可用,请避免在运行时 java.lang.NoClassDefFoundError,使这个包依赖真正成为可选的?

判断包在运行时是否可用的方法是尝试从中加载 class 并为 NoClassDefFoundError 做好准备。您可以在一个中心位置执行此操作,然后决定避免需要可选但不存在的包的代码路径。

PackageAdmin 可用于检查系统的包元数据。它已被弃用,您应该改用 BundleWiring。 因此,在您的 DS 中,您将依赖于 PackageAdmin/BundleWiring 并检查 cm 包是否已导出...