The manifest headers Import-Package and Require-Bundle are used to describe
a bundle’s dependencies.
Import-Package—This header is used to express a bundle’s dependency upon packages that are exported by other bundles. At runtime the framework analyzes the constraints and wires the bundles together.
Require-Bundle—This header is used to express a bundle’s explicit dependency upon other bundles by specifying a list of bundle symbolic names. A bundle that uses this header automatically has access to the packages exported by its required bundles.
Importing packages is recommended over requiring bundles as it results in a more flexible and loosely coupled system, offering system designers the ability to swap out implementations and deployments of function to suit their needs.
This point about imports is very important, so I will digress for a moment into a hopefully humourous, if somewhat exaggerated, analogy about shopping.
My wife and I have different approaches to shopping. I regard it as an onerous chore. When I must purchase something, I find a shop (or group of shops) that sells the items I need and I buy just those items and take them home. I don’t care which shop(s) I visit so long as I get the items I need.
In contrast, my wife goes to a shop she likes and basically buys everything in that shop.
Obviously I believe my approach is superior, because my wife has no control over what she brings home. If her favourite shop du jour changes its inventory then she ends up with different stuff… certainly lots of stuff she doesn’t need and perhaps missing some of the stuff she really does need.
It gets even worse… sometimes she ends up with an item that will not work on its own, because it has a dependency on something else, like batteries perhaps. So she has to go shopping again for batteries, and of course ends up buying the entire contents of the battery shop. Straining the analogy a little now, we could imagine that something else acquired from the battery shop also depends on something else, so she makes yet another trip to another shop, and another, purely to satisfy the requirements of a bunch of items that were not even needed to begin with! This problem is known as “fan-out”.
Hopefully the analogy with a module system is clear. The pathological shopping behaviour is equivalent to a system that forces us to import everything from the modules we declare a dependency on. When importing, we should import what we actually need to use, irrespective of where it comes from and ignoring all the things that happen to be packaged alongside it. We see the fan-out problem acutely when using the Maven build tool, which supports only whole-module (i.e. “buying-the-whole-shop”) dependencies, and as a result must download the entire Internet before it can compile a 200-byte source file.
To summarize, Require-Bundle is how Neil's wife shops. Import-Package is how Neil shops. My advice: shop like Neil.
3.12.3 Issues With Requiring Bundles The preferred way of wiring bundles is to use the Import-Package and Export-Package headers because they couple the importer and exporter to a much lesser extent. Bundles can be refactored to have a different package composition without causing other bundles to fail. The Require-Bundle header provides a way for a bundle to bind to all the exports of another bundle, regardless of what those exports are. Though this can seem convenient at first, it has a number of drawbacks.