我的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不满意。
osgi控制台中“ services”命令的结果包含以下内容:
{ServiceB}={service.id=180}
Registered by bundle: Z_2.12.0.qualifier [123]
No bundles using service.
ServiceB本质上是apache cxf Web服务,用于实现接口。该接口是从wsdl中生成的。 ServiceB以编程方式注册。 ServiceA引用了所生成的接口。此模式与另一个Web服务(例如ServiceC和ServiceD)完美配合。
如果有帮助,这种模式甚至可以在ServiceA和ServiceB之间起作用,直到我们升级了apache cxf。我以前没有提供此信息,因为我担心这会使问题变得过于复杂。
有两个要考虑的配置: 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在捆绑软件Z的激活器中打开。它使用“ WebServiceConfig”作为参数调用ServiceTracker的构造函数,因此,如果已注册提供接口“ WebServiceConfig”的服务,则将通知此ServiceTracker。现在,我们SeriveTracker的实现将读取属性“ webservice”,并以以下名称发布osgi服务:
context.registerService(serviceName, service, null);
之后,该服务将可用并在osgi控制台中激活。
通过我们的ServiceTracker注册后,可通过osgi控制台并通过源代码获得ServiceB:
ServiceTracker st = new ServiceTracker(bundleContext, "ServiceB", null);
st.open();
st.getService();
可以通过捆绑软件Z中的源代码访问ServiceB。但是不能通过捆绑软件A中的源代码对其进行访问。那么服务对象为null。
答案 0 :(得分:2)
我找到了一种解决方法,可以以编程方式访问ServiceB:
ServiceTracker st = new ServiceTracker(context, ServiceB.class.getName(), null);
st.open(true);
st.getService()
open方法中的boolean参数会有所不同。
不幸的是,我无法回答这个问题,为什么某些捆绑软件具有对ServiceB的“直接”访问权限(在open方法中不需要参数),而另一些则需要“ true”参数。