首页 文章

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

提问于
浏览
0

我遇到了equinox服务注册表实现的服务解析问题,我不确定这是不是一个bug .

这是我的包和运行时的简短描述:

Bundle com.foo.api

  • 使用接口IFooService导出com.foo.base

  • IFooService不是从ManagedService或与其相关的任何形式继承的

Bundle com.foo.impl

  • 进口com.foo.base

  • 进口org.osgi.service.cm

  • 注册实现IFooService的FooServiceImpl以及org.osgi.service.cm中的ManagedService

  • 这是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提供程序版本1.5

问题

根据config.ini中bundle的顺序,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,但是由IFooServiceImpl实现的接口ManagedService在com.foo.impl和com.foo.user之间不兼容 . 注册表不会返回服务引用 . 虽然声明性服务实现将依赖关系列为使用osgi控制台上的 comp 命令解析的 .

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

我没有在OSGi规范中找到任何声明,但在eclipse打开bug之前我想听听专家的想法 .

更新

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

  • Bundle A 请求IFooService,它只导入com.foo.api

  • Bundle B 请求IFooService,它导入com.foo.api和org.osgi.service.cm(但在"wrong version"中)

Bundle A 获取对服务的引用, Bundle B 没有 .

什么区别

  • "an interface is not known by a bundle"和

  • "an interface is imported in an incompatbile version"

什么时候这个接口在请求服务时没有被实际使用?

2 回答

  • 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

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

相关问题