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

时间:2014-07-04 08:51:26

标签: java osgi apache-felix

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

当我尝试通过调用

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

我的组件被停用,但由于某种原因,它会被重新激活,然后再次停用。 第二个激活/停用循环导致一些奇怪的行为,因为组件注册了一个“UI容器”,在关机期间导致应用程序的UI闪烁。

我的问题是什么可能导致第二次激活/停用循环?

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


下面的链接是来自停用/重新激活/停用方法的堆栈跟踪,在下面的答案中请求了这些方法:

deactivate stacktrace

re-activate stacktrace

deactivate stacktrace

1 个答案:

答案 0 :(得分:2)

我写了一个答案,因为它比评论更长(而且可能是答案):

  • ConfigAdmin在DS和包含您的组件的包
  • 之前停止
  • 当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)

了解源代码中重新激活标志的值为true的原因以及serviceReference函数的removedService参数的值。在调试视图中也可以找到堆栈跟踪此点的组件。因此,您将了解哪个组件已重新激活,并且基于哪个服务引用。您可以重新配置组件以仅连接唯一的服务引用。

我还考虑将邮件写入felix邮件列表,以计算重新激活标志,如果系统包处于停止状态,则不应重新激活组件。