Java 我的OSGi捆绑包多次意外启动和停止
我实现了一个OSGi包,它根据service.xml注入了一些其他服务。事实证明,如果激活策略设置为lazy,则我的包确实会被激活。其他服务被正确注入 主要问题是,根据注入的其他服务的数量,包会启动和停止几次。如果我将注入服务的数量减少到只有一个,那么捆绑包只启动一次。通过注入5个其他服务,它会启动和停止3次,其中最后一次启动没有停止,因此启动TCP服务器的服务可以正常工作。尽管它工作正常,但这种行为很奇怪,完全是无意的 我不知道如何避免这种情况,因为我不知道这是怎么发生的 日志: service.xml:Java 我的OSGi捆绑包多次意外启动和停止,java,osgi,osgi-bundle,equinox,Java,Osgi,Osgi Bundle,Equinox,我实现了一个OSGi包,它根据service.xml注入了一些其他服务。事实证明,如果激活策略设置为lazy,则我的包确实会被激活。其他服务被正确注入 主要问题是,根据注入的其他服务的数量,包会启动和停止几次。如果我将注入服务的数量减少到只有一个,那么捆绑包只启动一次。通过注入5个其他服务,它会启动和停止3次,其中最后一次启动没有停止,因此启动TCP服务器的服务可以正常工作。尽管它工作正常,但这种行为很奇怪,完全是无意的 我不知道如何避免这种情况,因为我不知道这是怎么发生的 日志: servic
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="activate" deactivate="deactivate" immediate="true" name="SimService">
<implementation class="SimServiceComponent"></implementation>
<service>
<provide interface="ServiceComponent"></provide>
</service>
<reference bind="setA" cardinality="1..1" interface="A" name="A" policy="static"/>
<reference bind="setB" cardinality="1..1" interface="B" name="B" policy="static"/>
<reference bind="setC" cardinality="1..1" interface="C" name="C" policy="static"/>
<reference bind="setD" cardinality="1..1" interface="D" name="D" policy="static"/>
<reference bind="setE" cardinality="1..1" interface="E" name="E" policy="static"/>
</scr:component>
谢谢你的帮助:-)
编辑:
此捆绑包中的服务不被任何其他捆绑包/服务使用,因此不存在循环依赖关系。将哈希代码标识添加到日志消息中是一个明智之举!它表明,尽管服务
A
、B
、D
和E
是恒定的,但服务C
的标识每次都会发生变化
这意味着由于某种原因,原始C
服务已从服务注册表中注销。由于您的SimServiceComponent
组件对服务C
有一个强制性的1..1
引用,因此当C
消失时,它将被强制停用。然后服务C
返回(更准确地说,注册了一个新的C
服务),允许重新激活您的组件
因此,您需要了解为什么
C
服务会循环。将哈希代码标识添加到日志消息中是一个明智之举!它表明,尽管服务A
、B
、D
和E
是恒定的,但服务C
的标识每次都会发生变化
这意味着由于某种原因,原始C
服务已从服务注册表中注销。由于您的SimServiceComponent
组件对服务C
有一个强制性的1..1
引用,因此当C
消失时,它将被强制停用。然后服务C
返回(更准确地说,注册了一个新的C
服务),允许重新激活您的组件
因此,您需要了解为什么
C
服务会循环。谢谢,我完全忽略了这一点。。。事实上,这可能是服务c中的一个bug,它不是我的工作,所以我无法对此做些什么。我想我现在必须接受它……如果你不能对服务C的稳定性做任何事情,那么你可以将你的引用更改为动态的和可选的。然后,当C服务交换出去时,您的组件将继续运行。当然,您需要以线程安全的方式访问它,并处理当您想要调用它时它可能不在那里的可能性。非常感谢!这个概念不适用于我的目的,但很高兴知道:-)。谢谢,我完全忽略了。。。事实上,这可能是服务c中的一个bug,它不是我的工作,所以我无法对此做些什么。我想我现在必须接受它……如果你不能对服务C的稳定性做任何事情,那么你可以将你的引用更改为动态的和可选的。然后,当C服务交换出去时,您的组件将继续运行。当然,您需要以线程安全的方式访问它,并处理当您想要调用它时它可能不在那里的可能性。非常感谢!这个概念不适用于我的目的,但很高兴知道:-)。
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="activate" deactivate="deactivate" immediate="true" name="SimService">
<implementation class="SimServiceComponent"></implementation>
<service>
<provide interface="ServiceComponent"></provide>
</service>
<reference bind="setA" cardinality="1..1" interface="A" name="A" policy="static"/>
<reference bind="setB" cardinality="1..1" interface="B" name="B" policy="static"/>
<reference bind="setC" cardinality="1..1" interface="C" name="C" policy="static"/>
<reference bind="setD" cardinality="1..1" interface="D" name="D" policy="static"/>
<reference bind="setE" cardinality="1..1" interface="E" name="E" policy="static"/>
</scr:component>
public void setA(final A a) {
LOG.info("Setting a {} for instance {} ", a.hashCode(), hashCode());
_a = a;
}
public void setB(final B b) {
LOG.info("Setting b {} for instance {} ", b.hashCode(), hashCode());
_b = b;
}
public void activate(BundleContext bundleContext) throws Exception {
LOG.info("Starting SimService now . . . {}", hashCode());
}