【发布时间】: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