Osgi equinox服务注册中心在服务实现两个接口时的行为

Osgi equinox服务注册中心在服务实现两个接口时的行为,osgi,equinox,osgi-bundle,Osgi,Equinox,Osgi Bundle,我对equinox service registry实现的服务解析有问题,我不确定这是否是一个bug 以下是我的捆绑包和运行时的简短描述: 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注册

我对equinox service registry实现的服务解析有问题,我不确定这是否是一个bug

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

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注册FooServiceImpl,它实现IfoosService和ManagedService
  • 这是FooServiceImpl的component.xml:

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

    它仅用于返回与请求者类型兼容的服务。您没有提供如何注册和查找相关服务的详细信息,以提供更明确的答案

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


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

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

    谢谢您的回复,我明白您的意思。修复原因比解决症状更有意义。不过,我认为com.foo.user.barComponentMPL应该获得对服务的引用,因为它只请求与实现兼容的IfoosService。服务可能实现的其他接口应该是无关的。或者有什么原因我目前还不知道?为了更好地理解,我在描述中添加了
    component.xml
    文件。如果您使用的是声明性服务,为什么还要在ManagedService上胡闹?声明性服务将为您处理所有配置管理交互。这是一个好问题。。。怪我。。。很明显,我错过了DS已经可以处理这件事的机会。这就解决了我的问题,非常感谢! <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> <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>