0

大家好。我们在 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 中的所有项目
  • 在命令行上重建项目

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

谢谢

4

3 回答 3

2

问题是您想要的服务可能尚未创建(尤其是在捆绑激活器中,因为某些捆绑可能尚未启动)。如果您仍想使用服务跟踪器,则需要提供一个 ServiceTrackerCustomizer,并在服务来来去去时跟踪(抱歉,不是双关语)。

或者,您可以切换到为您处理此问题的声明式服务。

于 2010-07-21T10:34:14.357 回答
1

使用 ServiceTrackers 并没有什么问题,除了它是一种相当低级的跟踪服务的方式。虽然我同意声明式服务是一种很好的机制,但因为“各种问题”而简单地解雇 ServiceTrackers 听起来像是一个糟糕的建议。

回到问题。

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

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

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

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

这是解耦的原因是您可能想要更新几个包,而不是在每个包之后“刷新”,而是推迟这样的刷新,直到所有包都更新。

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

于 2010-07-02T13:57:21.287 回答
0

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

您可能想查看这本书和相关的演示文稿,以获取有关为什么使用服务跟踪器是一个坏主意的更多信息。

http://equinoxosgi.org/

于 2010-07-02T13:20:57.003 回答