具有实现两个接口的服务的 Equinox 服务注册表行为

Behaviour of equinox service registry with service implementing two interfaces

我在 Equinox 服务注册表实现的服务解析方面遇到问题,我不确定这是否是错误。

这里是我的包和运行时的简短描述:

捆绑包com.foo.api

捆绑包com.foo.impl

捆绑包com.foo.user

运行时间

我正在使用 Equinox,在 config.ini 上述捆绑包中,org.eclipse.osgi.serviceorg.apache.felix.configadmin 已加载。 (当然还有其他人,但他们现在不感兴趣)

org.eclipse.osgi.serviceorg.apache.felix.configadmin 都提供包 org.osgi.service.cm

问题

根据 config.ini 中包的顺序,可能会发生 com.foo.user 没有得到对 FooServiceImpl[ 的引用=124=].

调试到 equinox 运行时我发现发生了这种情况:

  • com.foo.impl 使用 org.osgi.service.com 版本 1.4(来自 org.eclipse.osgi.service捆绑)
  • com.foo.user 使用 org.osgi.service.com 版本 1.5(来自 org.apache.felix.configadmin捆绑)
  • Equinox 注册表检测到接口 IFooServicecom.foo.user 所知,但接口 ManagedService 也由 IFooServiceImpl 实现,在 com.foo.impl[=228= 之间不兼容]。因此,注册表没有 return 服务引用。虽然声明性服务实现列出了在 osgi 控制台使用 comp 命令解决的依赖关系。

在这种情况下这是期望的行为吗?框架 return 不应该在请求 IFooService 时引用 FooServiceImpl 即使该服务实现了另一个不兼容的接口使用的包?

我没有在 OSGi 规范中找到任何声明,但在打开 eclipse 的错误之前,我想听听专家的想法。

更新

感谢 BJ Hargrave,主要问题已解决(见下文),但我仍然想知道为什么框架以不同方式处理这两种情况

  1. Bundle A 请求 IFooService,它仅导入 com.foo.api
  2. Bundle B 请求 IFooService,它导入 com.foo.apiorg.osgi.service.cm(但在"wrong version")

Bundle A 获取服务的引用,Bundle B 没有。

有什么区别
  1. "an interface is not known by a bundle" 和
  2. "an interface is imported in an incompatbile version"

当请求服务时没有实际使用此接口?

Shouldn't the framework return a reference to FooServiceImpl when requesting a IFooService even if the service implements another interface that is not compatible with the using bundle?

它仅指定给与请求者类型兼容的 return 服务。您没有提供有关您如何注册和查找相关服务的具体信息以提供更明确的答案。

此处的解决方案是不安装 org.eclipse.osgi.service 包。诸如此类的包(不相关的导出包的集合)会导致此类问题。 org.eclipse.osgi.service 在编译时很有用,因为您可以访问大量服务。但是在运行时,它会产生您所看到的那种问题。在运行时,最好让服务实现导出包,就像 Felix CM 所做的那样,或者让捆绑包仅导出服务包以支持实现及其客户端。

OSGi 提供了一个 osgi.cmpn.jar,类似于 org.eclipse.osgi.service,供在编译时使用。这个 jar 的最新版本包含一个无法解决的要求,以防止人们在运行时将 jar 作为一个包使用。

我同意 BJ 的观点,这可能是 OSGi 中的正常行为。您可以尝试解决问题的是为每个接口分别注册服务。如果仍然没有帮助,您可以创建一个单独的 class 实现 ManagedService,将配置更新转发到主服务。