OSGi 声明式服务处于活动状态,但未调用 bind()

OSGi declarative service is active, but bind() is not called

我在 OSGi 上下文中遇到了一个我不理解的声明性服务问题。我试着解释一下:

我有一个 FooService 需要 FooManagerService (1..1 static)FooManagerService 引用 FooService,但它是可选的 (0..n dynamic)。 目标是,如果 FooService 可用,它会在 FooManagerService 处注册(调用 bind() 方法),以便 FooManagerService 始终具有所有可用 FooService 系统实现。

它在 Windows 上运行良好,但在 Linux 上我遇到了问题,即 FooService 变为活动状态(调用了 activate() 方法),但那不是' 未被 FooManagerService 识别(未调用 bind() 方法)。如果我在 OSGi 控制台上手动禁用和启用 FooService,它会被 FooManagerService.

识别

我不明白,为什么会这样。可以通过增加 FooServiceImpl 所在的包的起始级别来避免这种情况。但这感觉像是一个丑陋的解决方法,这就是为什么我想了解那里发生了什么。

我附上一张描述服务之间参考的图片。任何提示表示赞赏。提前致谢!

此致

史蒂芬

Service Manager Diagram

这里有个循环,按理论应该没问题。但是在实践中遇到了很多问题

首先,您的实现应该是 immediate=true。这解决了一些问题,因为它防止了 DS 因为正在初始化而无法获得服务的讨厌问题。 IE。如果 FooManager 和 FooService impls 必须是立即的。 OSGi enRoute Cycles

中对此进行了描述

但是,还有一个问题 :-( Apache Felix DS 有一个错误,会导致您描述的效果。此错误与捆绑包排序有关。Apache Felix JIRA 5618 中报告了这一点。

如果这个 DS 错误是问题所在,那么不幸的是只有一个可靠的解决方案。不幸的是,因为它需要你深入到 OSGi 的内部。解决方法是手工注册manager service,并保证没有被DS注册:

@Component(service={}, immediate=true )
public class FooManagerImpl implements FooManager {

   private ServiceRegistration<FooManager> registration;

   @Reference
   volatile List<FooService> foos;

   @Activate
   void activate( BundleContext context, Map<String,Object> properties ) {
     registration = context.registerService(FooManager.class, this, new Hashtable<String,Object>(properties));
   }

   @Deactivate
   void deactivate() {
      registration.unregister();
   }

   ...
}

这里的技巧是 FooManager 在激活之前不会注册它的服务,而通常它是在激活之前注册的。

我知道 Apache Felix 正在处理它,但不知道他们的进展情况。

无论如何,循环 总是 糟透了。可悲的是,它们并不总是可以预防的,但我一定会尝试。

Note: registering a service manually will not create a capability. If you use Requirements/Capabilities you should add a service capability in the manifest to make the resolver work. If this line is gibberish to you, ignore it.