首页 > 解决方案 > osgi 服务:不满足活动服务的参考

问题描述

我有一个不满意的 osgi 服务:

ls 142
Components in bundle A: 
ID  State           Component Name          Located in bundle
90  Unsatisfied     ServiceA            A(bid=142)

对 ServiceB 的引用不满足:

comp 90
    Component[
    name = ServiceA
    activate = activate
    deactivate = deactivate
    modified = 
    configuration-policy = optional
    factory = null
    autoenable = true
    immediate = false
    implementation = ServiceA
    state = Unsatisfied
    properties = 
    serviceFactory = false
    serviceInterface = [ServiceA]
    references = {
        Reference[name = ServiceB, interface = ServiceB, policy = static, cardinality = 1..1, target = null, bind = setServiceB, unbind = unsetServiceB]
    }
    located in bundle = B_2.12.0.qualifier [142]
]
Dynamic information :
  *The component is NOT satisfied
  The following references are not satisfied:
    Reference[name = ServiceB, interface = ServiceB, policy = static, cardinality = 1..1, target = null, bind = setServiceB, unbind = unsetServiceB]
  Component configurations :
    Configuration properties:
      component.name = ServiceA
      component.id = 136
      objectClass = String[ServiceA]
    Instances:

尽管如此,ServiceB 仍处于活动状态:

ls 52
Components in bundle B: 
ID  State           Component Name          Located in bundle
14  Active      ServiceB            B(bid=52)

那么为什么不满足从 ServiceA 到 ServiceB 的引用呢?重新启动捆绑包 A(停止和启动)没有帮助。在捆绑包 C 中配置工作 ServiceC 上的引用会使 ServiceC 不满意。

更新:ServiceB 已注册

osgi 控制台中“服务”命令的结果包含以下内容:

{ServiceB}={service.id=180}
  Registered by bundle: Z_2.12.0.qualifier [123]
  No bundles using service.

附加信息:ServiceA 和 ServiceB 的配置、初始化和注册

ServiceB 基本上是一个 apache cxf Web 服务,它实现了一个接口。该接口是从 wsdl 生成的。ServiceB 以编程方式注册。ServiceA 具有对生成接口的引用。此模式与另一个 Web 服务(比如说 ServiceC 和 ServiceD)完美配合。
如果它有帮助:在我们升级 apache cxf 之前,这种模式甚至可以在 ServiceA 和 ServiceB 之间工作。我之前没有提供这些信息,因为我担心这会使这个问题变得过于复杂。

更新:组件ServiceB的配置

考虑配置有两个部分:xml 文件注册。xml 文件包含实现类“WebServiceConfigImpl”、提供的接口“WebServiceConfig”和一些属性。属性之一是 web 服务“ServiceB”——该服务的名称是稍后在启动过程中以编程方式注册的。

xml文件:

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="activate" deactivate="deactivate" name="ServiceB">
   <implementation class="WebServiceConfigImpl"/>
   <service>
      <provide interface="WebServiceConfig"/>
   </service>
   <property name="webservice" type="String" value="ServiceB"/>
   <property name="address" type="String" value="${adresse}"/>
   <property name="username" type="String" value="${benutzer}"/>
   <property name="password" type="String" value="${passwort}"/>
   (...)
   two references to other osgi services for resolving the web service configuration
</scr:component>

注册: 我们为此使用自己的 org.osgi.util.tracker.ServiceTracker。这个ServiceTracker是在bundle Z的Activator中打开的,它以“WebServiceConfig”为参数调用ServiceTracker的构造函数,所以如果提供了“WebServiceConfig”接口的Service已经注册了,这个ServiceTracker就会得到通知。我们的 SeriveTracker 实现现在读取属性“webservice”并以此名称发布 osgi 服务:

context.registerService(serviceName, service, null);

之后,该服务可用并在 osgi 控制台中激活。

更新:访问 ServiceB

通过我们的 ServiceTracker 注册后,可以通过 osgi 控制台和源代码访问 ServiceB:

ServiceTracker st = new ServiceTracker(bundleContext, "ServiceB", null);
st.open();
st.getService();

更新:访问 ServiceB 2

ServiceB 可以通过包 Z 中的源代码访问。但不能通过包 A 中的源代码访问。那么服务对象为空。

标签: osgi

解决方案


我找到了一种以编程方式访问 ServiceB 的解决方法:

ServiceTracker st = new ServiceTracker(context, ServiceB.class.getName(), null);
st.open(true);
st.getService()

open 方法中的布尔参数会有所不同。

不幸的是,我无法回答为什么有些捆绑包可以“直接”访问 ServiceB(open 方法中不需要参数)而有些捆绑包需要“true”参数的问题。


推荐阅读