Service OSGi服务跟踪器并不总是工作

Service OSGi服务跟踪器并不总是工作,service,osgi,eclipse-rcp,tracker,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) ma

嘿,伙计们。我们正在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.5版开始,Eclipse中对DS的支持就非常好

您可能想看看这本书和相关的演示文稿,了解更多关于为什么使用服务跟踪器是个坏主意的信息


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

您可能想看看这本书和相关的演示文稿,了解更多关于为什么使用服务跟踪器是个坏主意的信息


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

回到问题上来

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

进一步解释OSGi中的更新/刷新机制:

无论何时更新OSGi中的内容,都需要两个步骤

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

这种分离的原因是,您可能希望对多个bundle进行更新,而不是在每一个bundle之后进行“刷新”,而是将这种刷新推迟到所有bundle都更新为止


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

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

回到问题上来

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

进一步解释OSGi中的更新/刷新机制:

无论何时更新OSGi中的内容,都需要两个步骤

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

这种分离的原因是,您可能希望对多个bundle进行更新,而不是在每一个bundle之后进行“刷新”,而是将这种刷新推迟到所有bundle都更新为止


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

问题是您想要的服务可能尚未创建(特别是在bundle activator中,因为某些bundle可能尚未启动)。如果您仍然想使用服务跟踪器,您需要提供一个ServiceTrackerCustomizer,并在服务来来去去时跟踪(对不起,不是有意的双关语)

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