OSGi服务跟踪器并不总是有效

时间:2010-07-01 08:24:37

标签: service osgi eclipse-rcp tracker

嘿伙计们。我们在Eclipse RCP应用程序中使用OSGi服务。要跟踪它们,我们正在使用org.osgi.util.tracker.ServiceTracker类。该应用程序的示例代码如下所示

mailServiceTracker = new ServiceTracker(context, MailService.class.getName(), null);
mailServiceTracker.open();
MailService service = (MailService) mailServiceTracker.getService();

现在我的问题是,当我创建新服务时,getService()方法经常返回null。该代码适用于在应用程序中长时间存在的服务,但每次创建新服务时,我都要做很多事情,直到最终找到并跟踪服务。我经常尝试例如

  • '清洁......'在Eclipse中
  • '刷新'Eclipse中的所有项目
  • 在命令行上重建项目

有时这些事情会有所帮助,有时却没有。有没有人有这些跟踪器的经验,可以告诉我如何避免这种行为以及如何在创建后立即跟踪服务?

由于

3 个答案:

答案 0 :(得分:2)

问题是您可能尚未创建所需的服务(特别是在捆绑激活器中,因为某些捆绑包可能尚未启动)。如果您仍想使用服务跟踪器,则需要提供ServiceTrackerCustomizer,并在服务进出时跟踪(抱歉,没有双关语)。

或者,您可以切换到为您处理此问题的Declarative Services。

答案 1 :(得分:1)

使用ServiceTrackers没有任何问题,除了它是一种相当低级别的跟踪服务的方式。虽然我同意声明性服务是一个很好的机制,但由于“各种各样的问题”听起来像是一个糟糕的建议而只是解雇ServiceTrackers。

回到问题。

只要创建并打开了服务跟踪器,它就可以访问与您在创建时指定的过滤条件匹配的所有服务。那里没有延迟。我唯一能想到的是,你的捆绑包没有被正确解析,因此使用ServiceTracker对捆绑包B看不到从捆绑包A注册的服务。要检查这一点,首先找到导出包含服务接口的包的包,然后确保A和B实际都连接到它。

更多地解释OSGi中的更新/刷新机制:

每当您在OSGi中更新某些内容时,这都是一个两步过程。

假设您更新包含导出包的新版本的包。我们还假设有一些消费者进口它。只要您只更新捆绑包但未明确刷新连接(导出链接到哪个导入链接),消费者仍将连接到旧版本的包。只要您执行软件包刷新(您可以通过PackageAdmin服务在OSGi中执行此操作),您的使用者将再次得到解决,并将连接到新版本。

这是分离的原因是你可能想要对几个包进行更新而不是在每个包之后“刷新”,而是推迟这样的刷新直到所有包都更新。

这很可能就是你所看到的效果。最初您只进行更新,只有在刷新后,跟踪器才会真正看到新版本的服务。

答案 2 :(得分:0)

根本不是轻率,不要使用服务跟踪器。它们似乎使你的生活变得简单,但它们存在各种各样的问题。我建议您考虑使用Declarative Services。从3.5开始,Eclipse中对DS的支持非常好。

您可能需要查看本书及相关演示文稿,了解有关使用服务跟踪器的原因的详细信息。

http://equinoxosgi.org/