Why using Require-Bundle is a bad practice and should be avoided!

The discussion whether using entire bundles or packages as dependencies as always been very frequent among my team co-workers. So in order to provide you with some good arguments (in my belief) I provide here a full citation of a Manning’s publication which will give you good reasons for not using require bundle unless you have no other option.

Depending on packages, not bundles

Importing packages seems fairly normal for most Java programmers, because you import the classes and packages you use in the source files. But the import statements in the source files are for managing namespaces, not dependencies. OSGi’s choice of using package-level granularity for expressing dependencies among bundles is novel, if not controversial, for Java-based module-oriented technologies. Other approaches typically adopt module-level dependencies, meaning dependencies are expressed in terms of one module depending on another. The OSGi choice of pack-age-level dependencies has created some debate about which approach is better.

The main criticisms leveled against package-level dependencies is that they’re too complicated or fine-grained. Some people believe it’s easier for developers to think in terms of requiring a whole JAR file rather than individual packages. This argument doesn’t hold water, because a Java developer using any given technology must know something about its package naming. For example, if you know enough to realize you want to use the Servlet class in the first place, you probably have some idea about which package it’s in, too.

Package-level dependencies are more fine-grained, which does result in more meta-data. For example, if a bundle exports 10 packages, only 1 module-level dependency is needed to express a dependency on all of them, whereas package-level dependencies require 10. But bundles rarely depend on all exported packages of a given bundle, and this is more of a condemnation of tooling support. Remember how much of a nuisance it was to maintain import declarations before IDEs started doing it for you? This is starting to change for bundles, too; in appendix A, we describe tools for generating bundle metadata. Let’s look at some of the benefits of package-level dependencies.

The difference between module- and package-level dependencies is one of who versus what. Module-level dependencies express which specific module you depend on(who), whereas package-level dependencies express which specific packages you depend on (what). Module-level dependencies are brittle, because they can only be satisfied by a specific bundle even if another bundle offers the same packages. Some people argue that this isn’t an issue, because they want the specific bundle they’ve tested against, or because the packages are implementation packages and won’t be provided by another bundle. Although these arguments are reasonable, they usually break down over time.

For example, if your bundle grows too large over time, you may wish to refactor it by splitting its various exported packages into multiple bundles. If you use module-level dependencies, such a refactoring will break existing clients, which tends to be a real bummer when the clients are from third parties and you can’t easily change them. This issue goes away when you use package-level dependencies. Also,a bundle doesn’t usually depend on everything in another bundle, only a subset. As a result, module-level dependencies are too broad and cause transitive fanout. You end up needing to deploy a lot of extra bundles you don’t use, just to satisfy all the dependencies.

Package-level dependencies represent a higher-level view of the code’s real class dependencies. It’s possible to analyze a bundle’s code and generate its set of imported packages, similar to how IDEs maintain import declarations in source files. Module-level dependencies can’t be discovered in such a fashion, because they don’t exist in the code. Package-level dependencies sound great, right? You may now wonder if they have any issues.

The main issue is that OSGi must treat a package as an atomic unit. If this assumption weren’t made, then the OSGi framework wouldn’t be free to substitute a package from one bundle for the same package from another bundle. This means you can’t split a package across bundles; a single package must be contained in a single bundle. If packages were split across bundles, there would be no easy way for the OSGi framework to know when a package was complete. Typically, this isn’t a major limitation. Other than this, you can do anything with package-level dependencies that you can with module-level dependencies. And truth be told, the OSGi specification does support module-level dependencies and some forms of split packages, but their use is not recommended.

- Pedro D.

Loading Facebook Comments ...

2 thoughts on “Why using Require-Bundle is a bad practice and should be avoided!

  1. This article and many other on your website are very interesting.
    You should show your content to bigger audience.

    There is a big chance to go viral. You need initial boost and visitors will flood your site in no time.
    Simply search in google for:
    Juuri13 viral effect

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">