OSGi Import Package and Split Package Woes
July 14, 2009 | 3 min ReadSince 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 Require-Bundle
.
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 Require-Bundle
.
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 Import-Package
.
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 Import-Package
.
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 org.eclipse.ui
package.
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 org.eclipse.ui
.
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 Require-Bundle
usage.
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?