【问题标题】:My OSGi-bundle is starting and stopping unintentionally multiple times我的 OSGi 捆绑包多次意外启动和停止
【发布时间】:2018-04-23 13:10:16
【问题描述】:

我实现了一个 OSGi 捆绑包,它根据其 service.xml 注入一些其他服务。事实证明,如果激活策略设置为惰性,我的​​包确实会被激活。其他服务注入正确。

主要问题是,捆绑包会根据注入的其他服务的数量多次启动和停止。如果我将注入服务的数量减少到只有一个,则捆绑只启动一次。通过注入 5 个其他服务,它启动和停止 3 次,其中最后一次启动没有停止,因此启动 TCP 服务器的服务可以正常工作。尽管它工作正常,但这种行为很奇怪并且完全出乎意料。

我不知道如何避免这种情况,因为我不知道这是怎么发生的。

日志:

[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting a 23347814 for instance 28219381
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting b 260627 for instance 28219381
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting c 22735430 for instance 28219381
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting d 4256633 for instance 28219381
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting e service 27446331 for instance 28219381
[Component Resolve Thread] INFO A.B.SimServiceComponent - Starting SimService now . . . 28219381
[Component Resolve Thread] INFO A.OTHER - starting component
[Component Resolve Thread] INFO A.OTHER - starting component
[Component Resolve Thread] INFO A.OTHER - starting component
[Component Resolve Thread] INFO A.OTHER - starting component
[Component Resolve Thread] INFO A.OTHER - starting component
[Component Resolve Thread] INFO A.B.SimServiceComponent - Stopping SimService now . . . 28219381
[Component Resolve Thread] INFO A.B.SimServiceComponent - SimService stopped.
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting a 23347814 for instance 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting b 260627 for instance 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting c 28883317 for instance 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting d 4256633 for instance 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting e service 27446331 for instance 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - Starting SimService now . . . 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - Stopping SimService now . . . 606383
[Component Resolve Thread] INFO A.B.SimServiceComponent - SimService stopped.
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting a 23347814 for instance 33352835
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting b 260627 for instance 33352835
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting c 31287346 for instance 33352835
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting d 4256633 for instance 33352835
[Component Resolve Thread] INFO A.B.SimServiceComponent - Setting e service 27446331 for instance 33352835
[Component Resolve Thread] INFO A.B.SimServiceComponent - Starting SimService now . . . 33352835 

service.xml:

<?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());       
 }

感谢您的帮助:-)

编辑:

这个包内的服务不被任何其他包/服务消费,所以没有循环依赖。

【问题讨论】:

    标签: java osgi osgi-bundle equinox


    【解决方案1】:

    在您的日志消息中添加哈希码身份是明智之举!说明虽然服务ABDE是不变的,但服务C的身份每次都在变化。

    这意味着原始的C 服务由于某种原因已从服务注册表中注销。因为您的SimServiceComponent 组件具有对服务C 的强制1..1 引用,所以当C 消失时,它会被强制停用。然后服务C 回来(更准确地说,注册了一个新的C 服务),它允许您的组件被重新激活。

    因此,您需要了解C 服务为何循环。

    【讨论】:

    • 谢谢,我完全忽略了这一点……事实上,这可能是服务 c 中的一个错误,这不是我的工作,所以我对此无能为力。我想我现在必须忍受它......
    • 如果您对服务 C 的稳定性无能为力,那么您可以将引用更改为动态和可选的。然后,您的组件将在 C 服务换出时继续运行。当然你需要以线程安全的方式访问它,并处理当你想调用它时它可能不存在的可能性。
    • 非常感谢!这个概念不适用于我的目的,但很高兴知道:-)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 2012-10-10
    相关资源
    最近更新 更多