A Strained Shopping Analogy
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.
Favor Import-Package over Require-Bundle
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.
Karthik Shiraly wrote:Hi Jeff, Paul and Simon,
About OSGi integration best practices:
Every example I've seen on OSGi involves a call to OSGi API for looking up a service. But I see it as a deployment aspect (a side concern) and I feel an application should not include any kind of direct interaction with OSGi, except to be aware that there may be temporary unavailability of certain services. I feel it's better for OSGi to be used external to the application - more like an installer and internet aware updater.
Is there any framework / tool / approach to integrate OSGi in this manner? Does Equinox help in any way here?
Thanks for your time,
Aetius Flavius wrote:Hi,
Can OSGi be applied to J2EE web applications for example to seperate the concerns of business rules and presentation?