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

时间:2018-02-21 14:19:57

标签: java osgi apache-karaf

服务在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.`

一段时间后,第一个捆绑包启动,一切正常。

所以我的问题是如何强制第二个包等待第一个包开始?

1 个答案:

答案 0 :(得分:2)

在OSGi中,你永远不应该等待另一个捆绑或启动或服务出现。特别是永远不要在Activator中等待,因为它会阻止其他捆绑包的启动。

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

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

您可以想象,这对于跟踪单个服务并将其注入类实例很简单,但是一旦涉及更多服务和实例,这将变得非常困难。这就是您通常不应该使用普通OSGi API的原因。

所以你应该使用依赖管理框架,比如声明服务或蓝图,为你解决这个繁重的工作。