OSGi Import Package and Split Package Woes

OSGi Import Package and Split Package Woes

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 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?

  • Posted at 4:46 pm, July 14, 2009

    Matthias, the PDE team is working on enabling you to single source applications using one workspace.

    You will be able to set targets on a per project basis.

    I think this should help you with some of your problems.

    In regards to split packages… this is a difficult problem. However, it’s a reality that we need to deal with. I think in any long living OSGi system, you will see split packages appear as refactoring happens. I think this is evident in the Eclipse codebase.

  • Posted at 4:48 pm, July 14, 2009

    I agree, to a point. I usually tell my students to use R-B when expressing dependencies on the framework, but to strongly consider I-P for dependencies on their own bundles. I think it’s good to encourage teams to leverage bundle-level encapsulation as much as possible in their own code.

    — Patrick

  • Tom Seidel
    Posted at 4:52 pm, July 14, 2009

    I agree. I’m also very skeptical regarding import packages.

    I think, especially for RCP development (where you know which bundles will be in your target) a tighter coupling of modules makes often more sense, the import bundle way seems to me sometimes like a step backward to the good old “first jar on your classpath wins” pattern.

    The case you described can happen everywhere and as more bundles you have in your target the risk of a identically exported package name rises. The “split” declaration reads like a hack 😉

    IMHO you should consider very carefully if you’re using import packages, the often read flat said statement “use import packages” is simply wrong.

  • Adrian Sampaleanu
    Posted at 6:56 pm, July 14, 2009

    Sorry to say this, but I spent quite some time debugging my Eclipse environment (as a user with many non-base-install plugins) only to find out the problem was due to the use of Require-Bundle. In terms of satisfying a package dependency, OSGi will stop at the first bundle supplying a given package. In my case, the same third party artifact was packaged using different names and, as the particular package had already been found in a previously loaded bundle, a plugin using RB for a bundle containing the same package, failed to activate. This kind of problem can arise quite frequently when bundles depend on third party libraries that have been packaged by arbitrary, non-authoritative sources.

  • Posted at 7:03 pm, July 14, 2009

    I understand what you are writing, but I think you are coming to the wrong conclusion.

    In “normal” OSGi development (outside Eclipse RCP) using Require-Bundle is a bad practice, and I’d never even think of recommending it.

    What you are actually saying is that it is difficult to use Import-Packages in Eclipse RCP applications. If that is true (I don’t know RCP enough), that’s a weakness of the RCP platform; the same fact that you have often to deal with split-packages is a sign of a poor modularization.

    My experience, differently from yours… is in server side OSGi. In fairly big applications (around 150 bundles, with the usual enterprise stuff like Servlets, Spring, Hibernate and the like) I had to use exactly zero Require-Bundle statements; Import-Packages require of course a bit more discipline, but you gain a lot more flexibility. As for split-packages, I have seen literally a few cases, and most of them caused by some development error.

  • Posted at 7:11 pm, July 14, 2009

    Flilppo, I agree with you on principle. The new world may be nice if EVERYONE uses Import-Package only.

    In the Eclipse RCP case… Eclipse had its own plug-in model before it adopted OSGi (about 5 years ago). Eclipse models its dependencies using “Require-Bundle” semantics. When Eclipse adopted OSGi 5 years ago, these plug-ins (bundles) moved to having Require-Bundle embedded in them. So at Eclipse, we have a mix of Require-Bundle and Import-Package usage. The headache comes when dealing with split packages.

    If you haven’t seen split packages yet, you haven’t been working with OSGi long enough. What will eventually happen is that you will have someone create a bundle… exporting a package say ‘org.mycompany.logging’

    In this package let’s say you have two classes “Logger” and “Tracing” that are used by people. A customer now demands that they only want the Logger package and don’t care for tracing. So now you have to split this functionality across two bundles that export the same package… but have different classes in it.

    How do you not break people without split packages ;)?

  • Posted at 7:41 pm, July 14, 2009

    For bundles from org.eclipse I’m using required-bundle – or if only one or two packages are used also import-package.

    in my own projects (or customer projects) I encourage using import-package – think its better because it declares exactly the dependencies and hides unwanted.

    Using commonly used bundles (org.apache etc) I’m only using import-package – otherwise its problematic if you’re working with bundles from 3rdParty and you’re coupled to a specific bundle.


  • Posted at 7:59 pm, July 14, 2009

    Chris, perhaps I’m wrong,
    but in your example to avoid split packages I would create a new Bundle where Tracing is in a new Package,
    then the old Logger+Tracing bundle has optional import-package to the new Tracing bundle,
    and internal delegate from old Tracing to new Tracing.
    so if someone uses old Tracing this will work, who’s only using Logging has no Tracing bundle installed, so customer is satisfied. There will be other situations where it’s not easy, but first rule should be to avoid split packages if possible.
    But in Eclipse world split packages will happen as you described and of course no problems using require-bundle in this case.

  • Richard S. Hall
    Posted at 6:08 pm, July 15, 2009

    To be clear, the problematic issue with moving Eclipse to OSGi wasn’t the need for bundle-level dependencies by plugins. Require-Bundle could have been designed purely to be “importing everything the other bundle exports”. This wouldn’t have caused too much difficulty. This approach could not be taken specifically because Eclipse also had the need for split packages, which is something that was anathema to OSGi.

    It was decided to combine split package support with Require-Bundle as a way to limit their impact on the spec, but bundle-level dependencies and split packages are not really related. Still, even if Require-Bundle didn’t support split packages, I wouldn’t recommend them due to their brittleness. As it is, I would only recommend Require-Bundle if you are forced into a split package situation.

    And to correct the blog, split packages are not an OSGi concept, they are a Java concept. It is the default way packages are handled in Java (i.e., just keep searching the class path until you find the class), which is why JAR files allow you to do package sealing.

  • Posted at 6:18 pm, July 15, 2009

    Thanks for your comments and correction Richard, I’ve updated the post 🙂

    I agree with your recommendation… I only recommend Require-Bundle if you’re working with split packages or you don’t mind being coupled to a particular bundle. However, in general I still favor Import-Package given that the tooling is starting to catch up.

  • Posted at 4:36 pm, July 17, 2009

    You may be interested in the approach taken by SpringSource dm Server. We are aware of many of the semantic rough edges of split packages and yet we understood the need of enterprise application developers to specify a dependency on a whole bundle, particularly if they need exports because of function that will be woven into their application (e.g. from a persistence provider).

    So we introduced a macro form of import-package and spelled it “import-bundle”. At a very high level it has a similar feel to require-bundle but does not permit split packages. During deployment of the application, dm Server expands import-bundle into standard OSGi package imports.

    I suspect it may be worth standardising this in OSGi so that there would be a standard way of expressing a dependency on a whole bundle without the downsides of split packages.

  • Philipp Kursawe
    Posted at 9:50 pm, July 21, 2009

    I can not agree with you. I recently kicked out all R-B from our >50 bundle project and replaced it with I-P, including the required split packages for the Eclipse Workbench. We had not a single problem getting the app running again. The I-P gives you more flexibility and you can quickly exchange bundles the export a certain package. You can rename them, change their ID. It just does not matter as long as the required package is exported.

  • Posted at 2:56 am, November 6, 2009

    Matthias, thanks for pointing this out. I was just puzzled for an hour now why “Import-Package: org.eclipse.ui” is not provided by the bundle “org.eclipse.ui.workbench”, which clearly exports this package.

Post a Comment