java - OSGI 服务异常行为

标签 java service osgi equinox osgi-bundle

我正在经历我认为是 Osgi 服务及其跟踪的奇怪行为。

我有两个包:ProviderClient。提供商提供客户接收和使用的“通信服务”。

一开始,Client 通过 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 文件)并实现了绑定(bind)和解除绑定(bind)方法:

 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... 就会出现在控制台上。当我再次启动它时,收到了通讯!是消息。


到目前为止一切都很完美。但我想做最后的测试。我实现了绑定(bind)和解除绑定(bind)方法、组件定义,但我还让 ServiceTrackerClientActivator 上找到服务。

结果有点奇怪。

当我启动 OSGi 框架时,控制台上出现了 got comms!,就好像 DS 绑定(bind)方法正在工作并向我的 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,我会从解除绑定(bind)方法中收到此消息:*lost comms...*

如果我再次启动 bundle 会怎样?是的,“收到通讯了!”出现在控制台上......但是话又说回来,如果我看一下服务,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>

供应商和客户的 list 文件

提供者

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, ...

需要注意的是,我省略了文件夹、类和服务的真实名称,所以即使我的文本在类名、文件夹名称方面有任何错误......,我向你保证,真正的项目是正确构建的任何。

最佳答案

因此,如果我没理解错的话,您已经安装了以下包:

  1. 提供商使用 DS
  2. 提供商直接注册服务
  3. 使用 DS 的客户
  4. 使用 ServiceTracker 的客户

如果您启动所有这些 bundle ,您会看到 DS 客户端找到了其中一项提供者服务。您还会看到,如果您停止提供该服务的 bundle ,DS 客户端不会找到其他提供程序服务。这听起来可能很奇怪,但如果您设法划分了类空间,就可以解释这一点。要获得明确的答案,我们需要所有 4 个 bundle 的 list ,但我的猜测是 DS 客户端连接到其中一个提供商的导出,而另一个提供商具有不同的导出。

您没有看到使用 ServiceTracker 的客户端出现这一事实可以解释为您在代码中打开和关闭了该跟踪器。关闭后,OSGi 不再将服务视为“正在使用”。是的,您仍然保留引用,但您不知道该服务是否仍然存在。

那么让我们看看 list (也许还有 DS XML),看看我的理论是否正确。

关于java - OSGI 服务异常行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22477777/

相关文章:

c# - 如何在windows服务中发起HTTP请求?

java - Apache Felix mvn 包

java - 如何测量Java中的堆栈内存?

java - Eclipse Java 调试器 : easier way see values in the debugger that are in nested collections?

java - 如何以编程方式终止liferay中的 session /注销其他用户

android - Appcelerator Android 服务后台停止

java - Android中的定时弹出

linux - 无法将 Fuseki 作为服务运行

java - Indigo 目标平台缺少 javax.xml

maven-2 - pax-run 在 pom.xml 中使用 Maven 插件