【问题标题】:osgi service: reference on active service not satisfiedosgi 服务:不满足活动服务的参考
【发布时间】:2018-12-25 07:14:44
【问题描述】:

我对 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(停止和启动)没有帮助。在 bundle C 中配置一个工作 ServiceC 的引用会使 ServiceC 不满足。

更新:ServiceB 已注册

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

{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 可以通过 bundle Z 中的源代码访问,但无法通过 bundle A 中的源代码访问,则服务对象为 null。

【问题讨论】:

  • 你的组件 ServiceB 是什么样子的?我怀疑它没有导出服务。
  • @ChristianSchneider 这是一个很好的提示。我还在调查。
  • 能否将组件 B 的设置添加到问题中?
  • 这两个包可能没有使用包含 WebServiceConfig 接口的同一个包。
  • @BJHargrave 好点,但是这个接口(ServiceB)在我的工作区中只存在一次。所有捆绑包依赖项都设置为当前快照版本。包含接口的包只存在一次(也在运行时)。该接口包含在包 B 中。

标签: osgi


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-24
    • 1970-01-01
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 2013-04-17
    • 2011-01-10
    • 2014-07-19
    相关资源
    最近更新 更多