When should I use Import-Package and when should I use Require-Bundle?
OSGi allows for dependencies to be determined via Import-Package
, which just wires up a single package (exported from any bundle), and Require-Bundle
, which wires up to a specific named bundle's exports.
In building a greenfield OSGi application, which approach should I use to represent dependencies? Most of the bundles will be internal, but there will be some dependencies on external (open-source) bundles.
I believe Require-Bundle
is an Eclipse thing (that has now made it in the OSGi spec to accommodate Eclipse). The "pure" OSGi way is to use Import-Package
, as it specifically decouples the package from the bundle that provides it. You should be declaring dependencies on functionality that you need (the Java API provided by a certain version of a certain package) instead of where that functionality is coming from (which should not matter to you). This keeps the composition of bundles more flexible.
JavaScript analogy: This is like detecting whether a web browser supports a certain API versus inferring from what the user-agent string says what kind of browser it is.
Peter Kriens of the OSGi Alliance has more to say about this on the OSGi blog.
Probably the only case where you need to use Require-Bundle
is if you have split packages, that is a package that is spread across multiple bundles. Split packages are of course highly discouraged.
Favour Import-Package over Require-Bundle.
Require-Bundle:
- specifies the explicit bundle (and version) to use. If a requirde bundle needs to be refactored and a package moved elsewhere, then dependents will need changes to their MANIFEST.MF
- gives you accesss to ALL exports of the bundle, regardless of what they are, and regardless of whether you need them. If the parts you don't need have their own dependencies you will need those to
- bundles can be re-exported
- although discouraged, allows the use of split packages, ie: a package that is spread across multiple bundles
- can be used for non-code dependencies, eg: resources, Help etc.
Import-Package:
- looser coupling, only the package (and version) is specified and the run-time finds the required bundle
- Actual implementations can be swaped out
- Dependent packages can be moved to different bundles by the package owner
- But requires more metadata to be maintained (i.e: each package name) at lower levels of granularity