Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 调试OSGi组件激活/停用问题_Java_Osgi_Apache Felix - Fatal编程技术网

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

Java 调试OSGi组件激活/停用问题,java,osgi,apache-felix,Java,Osgi,Apache Felix,我试图调试一个问题,它似乎是由框架关闭期间我的一个OSGi组件的奇怪行为引起的 当我试图通过调用 context.getBundle(0).shutdown() 我的组件被停用,但由于某种原因,它被重新激活,然后再次停用。 第二个激活/停用周期会导致一些奇怪的行为,因为组件注册了一个“UI容器”,这会导致应用程序的UI在关闭期间闪烁 我的问题是什么会导致第二次激活/停用循环 我正在使用声明性服务Maven、ApacheFelix和SCR插件 下面的链接指向停用/重新激活/停用方法的堆栈跟踪,

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

当我试图通过调用

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

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

我正在使用声明性服务Maven、ApacheFelix和SCR插件


下面的链接指向停用/重新激活/停用方法的堆栈跟踪,这些方法在下面的回答中有要求:


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

  • 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以及
removedService
函数的
serviceReference
参数的值。还可以在debug视图中找到堆栈跟踪的这一点所在的组件。因此,您将知道哪个组件被重新激活,以及基于哪个服务引用。您可以将组件重新配置为仅连接唯一的服务引用


我也会考虑编写一个邮件到FeliX邮件列表,以计算如果系统束处于停止状态,它不应该重新激活组件的方式重新激活标志。或者两个不同的包提供了一个包的版本,可以满足包的依赖关系。@white我认为我没有循环依赖关系,这可能会导致应用程序在启动时失败。请您更详细地解释一下“2个不同的捆绑包提供…”的含义。假设您的捆绑包依赖于f.ex的某个包。版本[2.0,3.0],bundle1提供一些.package(v2.1),bundle2提供一些.package(v2.2),并且您已连接到bundle2。当bundle2停止时,您的bundle将停止连接到,而不是连接到bundle1并重新启动。@怀特,谢谢,我会再次检查并让您知道。在触发包刷新之前,bundle2不会重新连接。我已添加了您请求的堆栈跟踪,我到底应该查找什么?谢谢,您的回答帮助ed让我找到了问题所在。事实证明,该项目有多个相同组件接口的实现,并使用DS参考目标来区分它们。几周前,有几个地方被修改,开发人员忘记添加适当的目标。