如何配置 bundle 在引用的 bundle 启动后启动?

How to config bundle to start after referenced bundle starts?

服务在 xml 的第一个包中定义。

在第二个包中,使用相同的接口在 xml 中定义了一个引用。

在激活器的第二个包中,我通过以下方式获得服务参考:

ServiceReference servReference = context.getServiceReference(MyInterface.class.getName());

除非第一个包在第二个包之后启动,否则一切正常。

然后我得到:

org.osgi.framework.BundleException: Activator start error in bundle foo.bar.baz [123].
Caused by: java.lang.NullPointerException: Specified service reference cannot be null.`

过了一会儿,第一个包启动,一切正常。

所以我的问题是如何强制第二个捆绑包等待第一个捆绑包启动?

在 OSGi 中,您永远不应该等待另一个包、启动或服务出现。尤其不要在 Activator 中等待,因为它会阻止其他包的启动。

在您的情况下,您需要对 MyInterface 服务出现的事件做出反应。

如果您需要使用纯 OSGi API,那么您可以为此使用 ServiceTracker。您覆盖 addingService 和 removedService 方法,并在其中控制需要该服务的 class 的生命周期。因此,当服务出现时,您创建 class 的实例,注入服务并最终启动一些回调,让 class 知道服务在那里。当服务消失时,您告诉实例关闭。例如,参见 "Tracking a service".

正如您想象的那样,这对于跟踪单个服务并将其注入 class 实例很简单,但是一旦涉及更多服务和实例就变得非常困难。这就是为什么你通常不应该使用普通的 OSGi APIs.

因此,您应该使用依赖关系管理框架,例如声明式服务或蓝图,来为您完成这项繁重的工作。