Search code examples
osgiequinoxosgi-bundle

Behaviour of equinox service registry with service implementing two interfaces


I'm having a problem with service resolution of the equinox service registry implementation and I'm not sure whether this is a bug.

Here is a short description of my bundles and runtime:

Bundle com.foo.api

  • exports com.foo.base with an interface IFooService
  • IFooService is not inherited from ManagedService or in any form related to it

Bundle com.foo.impl

  • imports com.foo.base
  • imports org.osgi.service.cm
  • registers FooServiceImpl which implements IFooService and also ManagedService from org.osgi.service.cm
  • This it the component.xml of FooServiceImpl:

    
    <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

  • imports com.foo.base
  • imports org.osgi.service.cm
  • implements a component needing a IFooService (it does only request this interface and not the ManagedService interface)
  • The 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>
    
    

Runtime

I'm using equinox, in config.ini the bundles described above, org.eclipse.osgi.service and org.apache.felix.configadmin are loaded. (Beside others of course, but they are not of interest right now)

org.eclipse.osgi.service and org.apache.felix.configadmin both provide the package org.osgi.service.cm

  • org.eclipse.osgi.servce provides version 1.4
  • org.apache.felix.configadmin provider version 1.5

The problem

Depending on the order of the bundles in config.ini it can happen that com.foo.user does not get a refence to FooServiceImpl.

Debugging into the equinox runtime I found that this happens:

  • com.foo.impl uses org.osgi.service.com version 1.4 (from the org.eclipse.osgi.service bundle)
  • com.foo.user uses org.osgi.service.com version 1.5 (from the org.apache.felix.configadmin bundle)
  • The equinox registry detects that the interface IFooService is known by com.foo.user but the interface ManagedService which is also implemented by IFooServiceImpl is not compatible between com.foo.impl and com.foo.user. The registry therefor does not return a service reference. Although the declarative services implementation lists the dependency as resolved using the comp command at the osgi console.

Is this the desired behaviour in this case? Shouldn't the framework return a reference to FooServiceImpl when requesting a IFooService even if the service implements another interface that is not compatible with the using bundle?

I didn't find any statement in the OSGi specification, but before opening a bug at eclipse I wanted to hear what the experts think.

Update

Thanks to BJ Hargrave the main problem is solved (see below), but I'm still wondering why the framework handles these two cases differently

  1. Bundle A requests IFooService, it imports only com.foo.api
  2. Bundle B requests IFooService, it imports com.foo.api and org.osgi.service.cm (but in a "wrong version")

Bundle A gets a reference to the service, Bundle B doesn't.

Whats the difference between

  1. "an interface is not known by a bundle" and
  2. "an interface is imported in an incompatbile version"

when this interface isn't acutally used when requesting service?


Solution

  • Shouldn't the framework return a reference to FooServiceImpl when requesting a IFooService even if the service implements another interface that is not compatible with the using bundle?

    It is specified only to return services which are type compatible with the requester. You don't provide the specifics of how you register and find the service in question to provide a more definitive answer.

    The solution here is to not install the org.eclipse.osgi.service bundle. A bundle such as that (a collection of unrelated, exported packages), causes these sorts of problems. org.eclipse.osgi.service is useful at compile time since you have access to a large palette of services. But at runtime, it creates the sort of problems you see. At runtime, it is better to have either the service implementation export the package, as Felix CM does, or have a bundle export just the service package to support the implementation and its clients.

    OSGi provides a osgi.cmpn.jar, which is like org.eclipse.osgi.service, for use at compile-time. The latest versions of this jar include an unresolvable requirement to prevent people from using the jar as a bundle at runtime.