我正在尝试调试一个问题,这个问题似乎是由于我的一个OSGi组件在框架关闭期间的奇怪行为造成的。
当我尝试通过调用
来关闭框架时context.getBundle(0).shutdown()
我的组件被停用,但由于某种原因,它会被重新激活,然后再次停用。 第二个激活/停用循环导致一些奇怪的行为,因为组件注册了一个“UI容器”,在关机期间导致应用程序的UI闪烁。
我的问题是什么可能导致第二次激活/停用循环?
我正在使用声明服务Maven,Apache Felix和SCR插件。
下面的链接是来自停用/重新激活/停用方法的堆栈跟踪,在下面的答案中请求了这些方法:
答案 0 :(得分:2)
我写了一个答案,因为它比评论更长(而且可能是答案):
要查明是否是这种情况,请在激活和停用功能中插入以下内容:
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邮件列表,以计算重新激活标志,如果系统包处于停止状态,则不应重新激活组件。