【发布时间】:2014-04-24 00:57:51
【问题描述】:
我正在经历我认为是来自 Osgi 服务及其跟踪的奇怪行为。
我有两个包:Provider 和 Client。 Provider 提供 Client 接收和使用的“comm service”。
一开始,客户端通过 OSGi TrackerService 检索服务,这要归功于 ClientActivator 类上的这个方法:
private CommService retrieveCommService(BundleContext bc)
throws InterruptedException {
//create the tracker
ServiceTracker tracker = new ServiceTracker(bc, CommService.class.
getName(), null);
tracker.open();
//timeout of 5 seconds to find the service
CommService service = (CommService) tracker.waitForService(5000);
tracker.close();
return service;
}
这样,当Client 包的激活器被执行时,跟踪器就找到了服务。
如果 ServiceTracker 工作正常,这就是我在 OSGi 控制台上键入 services 时看到的内容:
{some.project.folder.imaComms.CommService}={service.id=46}
Registered by bundle: MA_Provider [2062]
Bundles using service:
MA_Client [2565]
无论如何,在阅读了一些关于 OSGi 服务的文档后,我决定使用 DS 而不是 ServiceTrackers。
所以,我创建了组件(提供程序和客户端 xml 文件)并实现了绑定和取消绑定方法:
public void setComms(CommService comm){
this.comm = comm;
System.out.println("got comms!");
}
public void unsetComms(CommService comm){
this.comm=null;
System.out.println("lost comms..");
}
而且,这一次,当我在控制台上键入 services 时,我看到的是:
{some.project.folder.imaComms.CommService}={component.name=
MA_Comm_Provider, component.id=18, service.id=47}
Registered by bundle: MA_Provider [2062]
Bundles using service:
MA_Client [2565]
所以,每当我停止 Provider 捆绑包时,控制台上都会出现消息 lost comms...。当我再次启动它时,得到了通信!是消息。
到目前为止一切都很完美。但我想做最后一次测试。我实现了绑定和取消绑定方法,组件定义,但我也让 ServiceTracker 在 ClientActivator 上找到服务。
结果有点奇怪。
当我启动 OSGi 框架时,got comms! 出现在控制台上,好像 DS 绑定方法正在工作并向我的Client 提供服务。但是,如果我输入 services,我得到的是这样的:
{some.project.folder.imaComms.CommService}={service.id=46}
Registered by bundle: MA_Provider [2062]
Bundles using service:
MA_Client [2565]
{some.project.folder.imaComms.CommService}={component.name=
MA_Comm_Provider, component.id=18, service.id=47}
Registered by bundle: MA_Provider [2062]
No Bundles using this service.
客户端正在通过 ServiceTracker 使用服务。如果我停止 ProviderService,我会从 unbind 方法收到这条消息:*lost comms...*
如果我再次启动捆绑包会发生什么?是的,“收到消息!”出现在控制台上...但话又说回来,如果我查看服务,service id 47(DS 服务)没有被任何人使用。 什么? O_o
有什么线索吗?提前致谢!
另外,忘了提一下:每当我重新启动 Provider 捆绑包时,Osgi 启动捆绑包大约需要 2-3 分钟,它会完全停止任何其他捆绑包的工作。
28/03/14 更新
提供者和客户端 DS 的 XML 文件
提供者
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="MA_Comms_Provider">
<implementation class="some.project.folder.maComms.CommServiceImpl"/>
<service>
<provide interface="some.project.folder.imaComms.CommService"/>
</service>
</scr:component>
客户
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="MA_Comms_consumer">
<implementation class="some.project.folder.maClient.MyClientImpl"/>
<reference bind="setComms" cardinality="1..1" interface="some.project.folder.imaComms.CommService" name="CommService" policy="static" unbind="unsetComms"/>
</scr:component>
提供者和客户端的清单文件
提供者
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: MA_Provider
Bundle-SymbolicName: MA_Provider
Bundle-Version: 1.0.0
Bundle-ClassPath: src/,
.
Bundle-Activator: myActivator
Export-Package: ...
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: ...,
org.osgi.framework;version="1.5.0",
org.osgi.util.tracker;version="1.4.2"
Service-Component: OSGI-INF/CommsProvider.xml
客户
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: MaClient
Bundle-SymbolicName: MA_Client
Bundle-Version: 1.0.0
Bundle-ClassPath: src/,
.
Bundle-Activator: ...
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: ...,
org.osgi.framework;version="1.3.0",
org.osgi.util.tracker;version="1.4.2"
Export-Package: es.techabout.meetabout.macomms
Service-Component: OSGI-INF/CommsConsumer.xml, ...
应该注意的是,我省略了文件夹、类和服务的真实名称,所以即使我的文本在类、文件夹的名称方面有任何错误……我向您保证真实项目的构建没有错误任何。
【问题讨论】:
-
你使用的是哪个 Osgi 实现?
-
春分。忘了说,对不起
-
您是否在提供者捆绑激活器中同时拥有通信服务的 DS 声明和服务注册?这会导致同一个服务被注册两次。
-
是的,我有它:“但我想做最后一次测试。我实现了绑定和取消绑定方法,组件定义,但我也让 ServiceTracker 在 ClientActivator 上找到服务”。问题是,它被注册了两次,并且 bind 和 unbind 方法都在工作......即使你,似乎也没有人使用 DS 服务!
标签: java service osgi equinox osgi-bundle