具有实现两个接口的服务的equinox服务注册表的行为

时间:2015-03-17 15:05:49

标签: osgi equinox osgi-bundle

我对equinox服务注册实现的服务解析存在问题,我不确定这是否是一个错误。

以下是我的捆绑包和运行时的简短描述:

Bundle com.foo.api

  • 使用 IFooService
  • 接口导出 com.foo.base
  • IFooService 不是从 ManagedService 继承的,也不是以与之相关的任何形式继承的

Bundle com.foo.impl

  • 导入 com.foo.base
  • 导入 org.osgi.service.cm
  • org.osgi.service.cm IFooService 以及 ManagedService FooServiceImpl >
  • 这是 FooServiceImpl 的component.xml:

    
    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"
     immediate="true" name="com.foo.impl.FooServiceImpl">
    
      <implementation class="com.foo.impl.FooServiceImpl"/>
        <service>
          <provide interface="com.foo.api.IFooService"/>
          <provide interface="org.osgi.service.cm.ManagedService"/>
        </service>
    
       <property name="service.pid" value="fooservice"/>
    </scr:component>
    
    

Bundle com.foo.user

  • 导入 com.foo.base
  • 导入 org.osgi.service.cm
  • 实现需要 IFooService 的组件(它只请求此接口而不是 ManagedService 接口)
  • component.xml

    
    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" 
       name="com.foo.user.BarComponentImpl" 
       enabled="true" immediate="true">
    
       <implementation class="com.foo.user.BarComponentImpl" />
    
       <reference interface="com.foo.api.IFooService" 
         name="fooService" policy="static" cardinality="1..1" 
         bind="bindFooService" unbind="unbindFooService"/>
    </scr:component>
    
    

运行

我使用equinox,在config.ini中,上面描述的包 org.eclipse.osgi.service org.apache.felix.configadmin 是加载。 (当然,除了其他人,但他们现在没有兴趣)

org.eclipse.osgi.service org.apache.felix.configadmin 都提供包 org.osgi.service.cm

  • org.eclipse.osgi.servce提供版本1.4
  • org.apache.felix.configadmin provider version 1.5

问题

根据config.ini中捆绑包的顺序, com.foo.user 可能无法获得对 FooServiceImpl 的依赖。

调试到equinox运行时我发现这种情况发生了:

  • com.foo.impl 使用 org.osgi.service.com 1.4版(来自 org.eclipse.osgi.service 捆绑包)
  • com.foo.user 使用 org.osgi.service.com 1.5版(来自 org.apache.felix.configadmin 捆绑包)
  • equinox注册表检测到 com.foo.user 已知接口 IFooService ,但接口 ManagedService 也由<< em> IFooServiceImpl 在 com.foo.impl com.foo.user 之间不兼容。注册表不会返回服务引用。虽然声明性服务实现将依赖关系列为使用osgi控制台上的comp命令解析的。

在这种情况下这是理想的行为吗?在请求 IFooService 时,框架是否应该返回对 FooServiceImpl 的引用,即使该服务实现了另一个与using bundle不兼容的接口?

我在OSGi规范中找不到任何声明,但在eclipse打开错误之前我想听听专家的想法。

更新

感谢BJ Hargrave解决了主要问题(见下文),但我仍然想知道为什么框架会以不同的方式处理这两种情况

  1. 捆绑A 请求 IFooService ,仅导入 com.foo.api
  2. 捆绑B 请求 IFooService ,它会导入 com.foo.api org.osgi.service.cm (但在&#34;错误的版本&#34;)
  3. 捆绑A 获取对该服务的引用,捆绑B 不会。

    之间的区别是什么
    1. &#34;捆绑包不知道接口&#34;和
    2. &#34;接口以incompatbile版本导入&#34;
    3. 在请求服务时未实际使用此界面?

2 个答案:

答案 0 :(得分:1)

  

在请求IFooService时框架是否应该返回对FooServiceImpl的引用,即使该服务实现了另一个与using bundle不兼容的接口?

仅指定返回与请求者兼容的类型的服务。您没有提供注册和查找相关服务的具体信息,以提供更明确的答案。

此处的解决方案是不安装org.eclipse.osgi.service捆绑包。诸如此类的捆绑(不相关的导出包的集合)会导致这些问题。 org.eclipse.osgi.service在编译时非常有用,因为您可以访问大量服务。但是在运行时,它会产生你看到的那类问题。在运行时,最好让服务实现导出包,就像Felix CM那样,或者让bundle只导出服务包以支持实现及其客户端。

OSGi提供osgi.cmpn.jar,类似于org.eclipse.osgi.service,可在编译时使用。这个jar的最新版本包含一个无法解决的要求,以防止人们在运行时将jar用作bundle。

答案 1 :(得分:1)

我同意BJ的说法,这可能是OSGi中的正常行为。您可以尝试解决问题的方法是为每个接口单独注册服务。如果仍然没有帮助,您可以创建一个实现ManagedService的特殊类,将配置更新转发到主服务。

相关问题