Posts Tagged ‘BND’

Recently I ran in to an interesting little problem with “resolution:=optional” OSGi directive. Basically what “resolution:=optional” says is that the even though the package imported with this directive is not present in the system  bundle would be resolved at run time. This is logical in case of compile time dependencies of the bundle not being needed at runtime. Or is it?..

I had to ponder a little while before putting down that last statement until I got how it can be so. Usually bundle needs compile time dependencies at run time as well to function correctly. But what if we have an execution path which never gets called at runtime inside our bundle. If that execution path contains imports then these import dependencies will not be needed at run time.

Typically Maven Bundle Plugin is used to incorporate bundle creation at build time. So in this case the general practice I used to follow was to explicitly import obvious dependencies and use a “resolution:=optional” directive with “*” wild card as a catch all mechanism for all other imports. Even if we include some imports which are not needed at runtime we can get away with optional directive since bundle will resolve without them, right?

This is all good and rosy until p2 come in to the picture. Apparently p2 installs bundles exporting optional imports too if it can find them during provisioning. So you end up installing bundles that may  not required at runtime along side the feature. Though generally not disastrous this is a concern if you want to keep your feature installation lean.

In my case the issue was some unwanted bundle getting mysteriously installed with my feature even though it’s packages are not explicitly imported in any of bundle’s sources. As it turned out I had included a dependency required for tests without specifying it should be in the test scope. So naturally with “*;resolution:=optional” in place the Bundle Plugin dutifully did it job by placing an import in the manifest which led to this particular bundle installation at provisioning time.

Solution was trivial. Place the dependency in test scope and Bundle Plugin did not include an import since test scoped dependencies will not be imported in the manifest at all. Alternatively I could have explicitly unimported the offending packages or make requires.greedy instruction false at feature p2.inf to stop P2  greedily installing optional dependencies [1] though these solutions are hacky which do not deal with the root cause directly in my case. But it’s always to good to have alternatives isn’t it?. :).

[1] http://ekkescorner.wordpress.com/2010/04/26/p2-is-my-friend-again/

Read Full Post »

I use Maven Bundle plugin a lot since our projects are OSGi based. Basic idea I had of this plugin is that this plugin makes an OSGi bundle out of a normal jar (basically by augmenting the META-INF file) if we do declare exported and private package information correctly in it’s configuration section in the POM declaration. Normal procedure followed would be to copy the configuration from an existing POM and tweaking it according to the current project requirements. My knowledge about it was just about it until recently. It was when I bumped up on a strange issue one day I was forced to read more on the subject and fortunately solution was not that far away with the amount of comprehensive documentation and FAQ section found at plugin’s site [1].

So why am I making a blog out of this if all what you want to know is well documented somewhere else?

Well, mostly to document some points which do matter, in a concise point form as a future self reference rather than going through the lengthy documentation every time when my memory fails me. (Not a rare occurance I would say.. :)).

So here goes.. My points with bullets.. :).

  • <Export-Package> will copy the packages to the bundle and export them in the MANIFEST while <Private-Package> will copy the packages to the bundle even-though they will not be exported.
  •  If you want a class to be included in the bundle make sure the package that it lives in is present in either of these instructions or otherwise it will not get included in the bundle.
  •  If <Export-Package> and <Private-Package> overlaps <Export-Package> takes precedence.
  • Using negation “!” in <Export-Package> declaration will result in package being not included bundle and not exported as well.
  • If a negation following an non-negated package declaration overlaps with the non-negated package declaration, the negated package pattern will not take effect. Always put negations first in  <Export-Package> instruction to avoid these kind of issues.
  •  Plugin generates the Import-Package bundle manifest header based on the Java imports present in the classes of the bundle so generally it’s not needed to specify it explicitly.
  • If a referenced packages do not need to be available for at runtime for bundle to perform its intended task (e.g: only a test scoped class using the package which is only needed during test runs..) use negation inside not to import it.
  • If you need to import a package not referenced by any class in bundle use resolution:=optional directive after the package name as follows.


   The bundle would resolve even if the package is not present at runtime.

  • Use to import a dynamically loaded class (e.g: Using Class.forName()) given that it’s exported in originating bundle. Generally using “*” wild-card would do, since it will enable loading any dynamically loaded class in other bundles given that the package it lives in has been exported by those bundles.

So that’s about it for my notes. If you want a good tutorial have a look at [2] as well. By the way in case you are wondering about the issue I had, the second point sums it up pretty nice. :).

[1] http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html

[2] http://wso2.org/library/tutorials/develop-osgi-bundles-using-maven-bundle-plugin

Read Full Post »