Since OSGi developers gained influence in the Eclipse development and trainings discussion… many words have been said in favour of declaring dependencies via
Import-Package instead of
The concept of
Import-Package is quite appealing. In today’s world, Java itself doesn’t have a concept for modules so we depend on OSGi for modularity. Actual dependencies on the Java side are specified on the class and package level. So it feels more natural to specify what you need via
Import-Package instead of where you want something from via
As an experienced Eclipse developer dealing with many large projects… I’ve lost some enthusiasm for
Import-Package. All those different bundles and their dependencies are difficult enough to grasp for newcomers.
Require-Bundle has better tooling support in Eclipse and less complexity in general… so I recommend to use
Require-Bundle unless someone needs the improved flexibility of
What’s the reason for my attitude?
Recently I spent some time with a single-sourcing a RAP/RCP project. Having different target platforms for the same bundles is a perfect example where you need the flexibility of
Import-Package. Flexibility is good, right? So I went ahead and declared all dependencies as
Now imagine you have declared an
Import-Package to the
org.eclipse.ui bundle, being sure that org.eclipse.ui is exported in your target.
Everything is fine, right? So far so good in the typical Eclipse RCP case.
However, it’s not so fine if you try it with RAP although you’ll find that bundle
org.eclipse.rap.ui.workbench exports the
So the situation is:
my.bundle imports org.eclipse.ui org.eclipse.rap.ui.workbench exports org.eclipse.ui
However, your bundle just won’t be resolved due to a missing
Import-Package constraint on
The diagnostics in Equinox don’t help much either… it just tells you exactly the above imports and exports. I don’t know if there are better tools out there to diagnose issues.
The reason for this behavior is a concept in Java called split packages. It allows the same package to be declared across several bundles… giving each split a special name. So it’s something like a sub-package concept for packages. Although it is discouraged in the OSGi specification… it is used by the Eclipse workbench and other areas where there has been a lot of refactoring and
The correct import declaration in my.bundle would be
Import-Package: org.eclipse.ui; ui.workbench="split"
Why does it work in the RCP target case?
It wouldn’t if your target platform contains RCP only. However, most RCP applications have the bundle
org.eclipse.ui.ide in their target platform which exports another split of the
org.eclipse.ui package. OSGi only resolves split packages if at least two exported split packages can be found.
Knowing this… I now can safely use
Import-Package for my single-sourced applications. However, I don’t see a way how I possibly could recommend this to students in my training courses or new people to OSGi in general. I’d need to tell them “Look,
Require-Bundle is something that has been used in Eclipse for awhile, mostly for legacy reasons. We don’t recommend its use any more.
Import-Package is better if you want looser coupling between bundles. However, be aware of the pain split packages can cause.”
I guess my gripe is that split packages make things complicated and we need better tooling to support them.
How are other people handling split packages in the wild?