Blog / 2007-05-21 aQute - Software Consultancy
Search
*

Why You Need Bnd

Just received a Google Alert about OSGi from a blog. The author, Jilles van Gurp, first praises OSGi only to strike at the tools. His key problem is the way you have to add imports to the manifest one by one in the Eclipse PDE, and then some rants about the retarded manifest format.

I could not agree with him more. The Bnd tool seems to take care of all his objections.

Managing dependencies to other bundles is more cumbersome than handling imports in Java. Normally when I want to use some library, I download it; put it on the classpath; type a few letters and then ctrl+space myself through whatever API it exposes. In OSGi it’s more difficult. You download the bundle (presuming there is one) and then need to decide on which packages you want to use that it exposes.

I agree, the Eclipse JDT works much nice than the PDE. However, if you use bnd, you work exactly the way you describe. You can use libraries just like you used them before, you do not even have to use the PDE. I only use the Eclipse JDT for my work. Bnd will read a recipe that describes what parts of the classpath should be put in the resulting bundle. Wildcards and calculated defaults make it possible to keep the description to the absolute minimum. Bnd will then calculate the contents and the required imports.

Also most libraries don’t actually ship as bundles. Bundles are a new concept that is not backwards compatible with good old jar files (which is the form most 3rd party libraries come in). This is an unnecessary limitation. A more reasonable default would be to treat non OSGi jar files as bundles that simply export everything in it and put everything it imports on the import path. It can’t be that hard to fish that information out of a jar file. At the very least, I’d like a tool to that for me.

Well, your wishes are granted, again, with the Bnd tool. The tool has a wrap function that does exactly that. However, in reality it is slightly harder because many JARs are extremely messy in their dependencies. It is usually necessary to create optional imports or ignore imports to make the bundles installable. When you analyze a JAR (which Bnd can help you with) then you are often surprised how many unused (or rarely used) dependencies are present.

Finally, I just hate having to deal with this retarded manifest file concept. I noticed the bug that requires the manifest to end with a empty line still exists (weird stuff happens if this is missing). This is equally annoying as the notion of having to use tabs instead of spaces in makefiles.

Hmm, it becoming boring but with Bnd you also no longer have to worry about those trivialities. A bnd file is a properties file. It can handle unlimited line lengths, lines can be extended to the next line with a \, and who cares about the last line? You can also add comments. Bnd reads these properties and generates a valid manifest using the Java built in Manifest class. Along the way it verifies all the headers for correct values. Just a peek, this is how a simple Bnd file could look like:

  Export-Package: aQute.service.*
  Import-Package: javax.servlet.http;version="[2,3)", *

However, Jilles was not finished yet with his criticism of OSGi:

Of course with version 1.5 there is now a nicer way to do this using annotations. Understandably, OSGi needs to be backwards compatible with older versions (hence the kludge is excused) but the way forward is obviously to deprecate this mechanism on newer editions of Java. Basically, I want to be able to specify at class and method level constraints with respect to import & export.

I know annotations are becoming in fashion lately, and they clearly have their use. However, there is also the issue of separation of concerns. I think our industry has learned the hard way that you do not want to clutter business logic with infrastructure. Specifying your constraints on classes or methods with annotations will clearly clutter your code. I really think dependencies are too complicated for humans to manage. Better tools are needed, letting the user manage these dependencies by hand in the code is extremely error prone. So I am not sure annotations are the solution. Bnd can find out the versions of imported packages if they are versioned at the source (either in the manifest of via a packageinfo file in the package directory). This at least is simple and consistent, though it can not handle version ranges. I have some ideas how I could handle version ranges (by allowing multiple versions of the same package on the classpath and analyzing the differences). However, time ...

An additional problem is that packages don’t really have first class representation in java. They are just referred to by name in classes (in the package declaration) but don’t have their own specification. That means it is difficult to add package level annotations (you can work around this using a package-info.java file).

Again, as stated before I am not sure if annotations are the best solution because they clutter the business logic. In OSGi you can add attributes on a package through the manifest (or Bnd).

Additionally, Bnd has many more features:

  • Bnd is also used in the Maven build tool with the Felix Maven-bundle plugin.
  • Bnd is also an Eclipse plugin, it adds entries at the context menu for .bnd files and .jar files.
  • You can pull in resources from anywhere of the file system or with a URL. This does not require first creating a directory structure with all the resources, the JAR is build on the fly.
  • Resources can contain variable references that are substituted.
  • You can easily place packages from the classpath in your JAR file. This is extremely handy if you use a small part of another bundle and do not want to create extra dependencies.
  • Bnd also creates the uses clause on exports. The uses clause indicates what packages a package uses. The framework uses this information to create consistent class spaces.
  • You can inline other JARs or directories
  • Much much more.

I am not saying Bnd is perfect. I wish I could spend the time to extend it in the ways I would like to: a graphic editor for the dependencies, better analysis support, integration with the Eclipse builder, etc.

Peter Kriens
Copyright 2006 aQute SARL, All Rights Reserved