调试OSGi组件激活/停用问题



我正在调试一个问题,这个问题似乎是由我的一个OSGi组件在框架关闭期间的奇怪行为引起的。

当我试图通过调用

关闭框架时
context.getBundle(0).shutdown()

我的组件被停用,但由于某种原因它被重新激活,然后又被停用。第二个激活/停用周期会导致一些奇怪的行为,因为组件注册了一个"UI容器",这会导致在关闭时应用程序的UI闪烁。

我的问题是什么可能导致第二次激活/失活周期?

我正在使用声明式服务Maven, Apache Felix和SCR插件。


下面的链接是来自deactivate/reactivate/deactivate方法的堆栈跟踪,这些方法在下面的回答中被请求:

关闭加亮加亮

重新激活

关闭加

我写了一个答案,因为它比注释长(它可能是答案):

  • ConfigAdmin在DS和包含组件的bundle之前停止
  • 当ConfigAdmin停止时,它触发一个配置不再可用的事件
  • 您的组件以不需要配置的方式配置,因此由于已经存在的配置消失的原因而停止,并在组件不需要配置时重新激活

要了解是否存在这种情况,请在激活和停用功能中插入以下内容:

Thread.dumpStack();

然后将堆栈跟踪复制到您的问题中。

如果是这种情况,您可以通过在组件上设置所需的配置策略来解决它。

我所做的(您也可以这样做)来比较停用和重新激活的堆栈跟踪。您将在差异开始处找到有用的信息。

基于上传的堆栈跟踪:对提供间接引用服务的组件进行去激活,然后重新激活。原因:

它的一个依赖项(引用消失),但另一个满足组件。

重新激活堆栈跟踪的有趣部分如下:
at org.apache.felix.scr.impl.manager.AbstractComponentManager$3.register(AbstractComponentManager.java:972)
at org.apache.felix.scr.impl.manager.RegistrationManager.changeRegistration(RegistrationManager.java:134)
at org.apache.felix.scr.impl.manager.AbstractComponentManager.registerService(AbstractComponentManager.java:1024)
at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:818)
at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.removedService(DependencyManager.java:946)
at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.removedService(DependencyManager.java:871)
at org.apache.felix.scr.impl.manager.ServiceTracker$Tracked.customizerRemoved(ServiceTracker.java:1503)

如果可以,请在组件的激活函数中添加一个断点。在重新激活期间,查看堆栈跟踪并执行以下行:

at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.removedService(DependencyManager.java:946)

查看为什么源代码中的reactivate标志的值为true,并且removedService函数的serviceReference参数的值为true。还可以在调试视图中找出您在堆栈跟踪的这一点上所处的组件。因此,您将知道哪个组件被重新激活,以及基于哪个服务引用。然后,您可以重新配置组件,使其仅连接唯一的服务引用。

我还会考虑给felix邮件列表写一封邮件,以计算重新激活标志,如果系统包处于停止状态,它不应该重新激活组件。

最新更新