3
votes

Given two OSGi bundles foo and bar, and:

  • bar imports (Import-Package:) packages from foo.
  • bar implements a service which is defined in foo.

Is it allowed that a service in foo uses (@Reference) the service from bar (according to OSGi specification)?

It should be technically possible by first resolving the bundles and then starting the services in an order which meets their dependencies.

(I'm less interested whether some specific OSGi implementation supports it.)

EDIT Background: This way, an OSGi bundle could provide custom service implementations for some library (SPI)

1

1 Answers

2
votes

@Reference is an SCR annotation for service component runtime specification. You have to distinguish resolution phase (process between installing a bundle and making it active) and service references wiring.

Sticking to SCR components - you can imagine two components, both exporting (@Service annotation) some service and referencing each other (using @Reference) - this way you head into deadlock situation.

But the scenario you described seems fine.

  1. bar imports packages from foo - so it's resolved after foo. Of course if you install bundles manually and you first install bar and then foo, you have to refresh/restart bar
  2. foo @References services from bar - it only means that SCR runtime will activate given SCR component in foo after the service is available

Karaf using its features adds another layer of resolution (standard OSGi resolver) for bundles of the features. So it's always better than installing bundles manually (or dropping them all to some auto-deploy directory).

Also remember one thing. If somehow, your bundle gets Import-Service (or Require-Capability) manifest header (these may be generated by maven-bundle-plugin), resolution may fail, because services are usually registered asynchronously later, after starting the bundle (using blueprint or scr runtimes). I personally usually get rid of these headers using this configuration:

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <extensions>true</extensions>
  <configuration>
    <instructions>
      <_removeheaders>Import-Service,Require-Capability</_removeheaders>
...
    </instructions>
...