[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re[2]: [equinox-dev] RequiresBundle, ImportPackage and virtual providers

1. The only difference between Require bundle and Import Package is
   granularity. There are -no- lifecycle differences. Actually,
   require bundle is internally transformed to the same wires as import
   package uses. Note that also packages should be versioned. Again,
   there are no differences but granularity.

2. If you have sloppy exported packages, you probably also have sloppy
   virtual bundles. All bets are off. A package with the same version,
   and same name MUST contain substitutable content. If you do not
   accept this condition, then please skip :-) the remainder of this message;
   package atomicity is one of the premises of OSGi modularity.
   
3. Packages can be grouped. The uses constraint ensures that packages
   that belong together come from the same exporter. It is therefore not
   possible that package p and comes from bundle A and q from bundle B
   when p and q are required to come from the same bundle. Packages
   can only come from a single source bundle (with require
   bundle can you create split packages, but they look as if they came
   from a single source). So Import-Package has the power to group
   related items on a smaller scale than the bundle (which is only the
   packaging).

4. Your example with javax.xml works very well with package imports
   and services but also with the JAXP SPI model. Actually, using
   Import-Package allows you to use ANY JAXP parser, not just the ones
   that the developer had thought of ahead of time. The same for other
   SPI models like java.sql, javax.crypto, java.servlet, etc.

6. Being able to choose the bundles you install is a very powerful
   tool in the hands of the deployer. Because Import-Package minimizes
   the coupling between bundles, the deployer has more flexibility.
   Which imho is VERY important (ever had to solve a problem only to
   find out that the programmer had made it impossible for no
   technical reason whatsoever? You call it infected, I many times
   would have called it a lifesaver if I could replace bundles with
   alternatives).

Reading your mail I think you have a few misconceptions about the
modularity layer of OSGi, where the fact that a package is a first
class citizen is the foremost issue.

I take the blame by not providing sufficiently clear descriptions :-( I hope
I have clarified some of these issues here. However, this is a complex area and I could obviously miss something.
In my opinion, the javax.xml.parsers example is better done with Import-Package
(javax.xml.parsers package has a clear spec version) because it leaves
the deployer more freedom and requires less work. If you have a better
example (where you accept that a a package is an atom), we can analyze it.

Hope this helps, kind regards,

     Peter Kriens



















AB> On 30/03/06, Peter Kriens <Peter.Kriens@xxxxxxxx> wrote:
>> First I am not sure why Xerces or Crimson needs to be started? My
>> assumption always was that they implement JAXP ...

AB> It was meant as an example that would easily be understood in terms of
AB> an interface and separate implementations, as opposed to other issues
AB> specifically related to XML parsing.

>> A client should only bind to the package it uses, in this case
>> javax.xml.parsers. Initialization ordering can be handled by using the
>> XML service.

AB> This is the key problem, for me. A package is an open-ended bucket, to
AB> which not only this bundle, but *any* bundle, can contribute classes
AB> to. It's an implementation facet. There's nothing to stop other
AB> bundles inserting (or attempting to replace) items in this package on
AB> a piecemeal basis. A bundle, on the other hand, is a closed collection
AB> of code that I can depend on as a black-box unit. A package is *not* a
AB> black box.

AB> It works fine in the lowest level a-service-is-just-a-single-interface
AB> (see other comments regarding LogService) because then your package is
AB> trivial, and there's only one interface in it. However, almost all
AB> bundles are complex containers that can have many different aspects to
AB> their code. You don't want to have to specify a complex service (or
AB> indeed, not a service at all) as an open-ended package just because
AB> that's the only way it can work. What's to stop two separate bundles
AB> contributing overlapping code to the same package? Which one 'wins' in
AB> that situation? Can I provide the equivalent of aspect-oriented
AB> programming simply by replacing the contents of a package because it's
AB> been made open by the use of liberal export/import packages?

>> I am not sure I understand your comments about Linux? This sounds
>> awfully close to how it works with services. I express my dependency
>> on javax.xml.parsers and look for the DocumentBuilderFactory and
>> SAXParserFactory services. Depending on the installed bundle set and
>> imported package version I get the parser my deployer wanted me to use.

AB> My mentioning of the Linux alternatives was another system that uses a
AB> way of providing a loose coupling between systems that can be replaced
AB> at run-time. But it's not the same as services. An OSGi service can be
AB> started or stopped independently of bundles that depend on it; they
AB> may not even be able to acquire a service, even though the package is
AB> there. On the other hand, if I have a bundle dependency, then I can
AB> guarantee that that bundle is started before mine is and will remain
AB> started for the lifetime of my bundle.

>> Your virtual bundle creates a meeting point to break the coupling between
>> the client and the implementation. This is EXACTLY the purpose of the
>> service model.

AB> It's the same purpose, but they differ in implementation. Bundles are
AB> explicitly tied together by their lifecycle; services aren't. Bundles
AB> define a closed set of code which may span multiple packages without
AB> being infected with other code; import-packages use an open set of
AB> code which allows any bundle to contribute detritus to a package which
AB> may be subsequently installed. Bundles can be versioned;
AB> import-packages can't be. Furthermore, you're assuming that there is a
AB> service here; there's no reason to assume that that's the case. I may
AB> just want to be able to (say) parse Atom feeds, and I don't really
AB> care how. What I want is to be able to switch implementations that
AB> conform to a common API, *not* a common package.

>> So you can have your cake and eat it too with services. You can use
>> import-package which is much more robust over time than require bundle,
>> and you can easily switch implementation packages by managing the set
>> of installed bundles.

AB> Yes, I believe that you are. It's not that what you say can't be done
AB> with services (it can) but it's what else can/cannot be done. I could
AB> have (say) an AtomParser that picked apart XML and returned me Atom
AB> entries either as an OSGi service (imported with Import-Package), or
AB> use the concept of virtual bundles. However, just because you can do
AB> that in either way it doesn't mean they're equivalent. If I were using
AB> Import-Package and the OSGi services, then I could contribute or
AB> replace code from that service by having a second bundle with an
AB> Export-Package. Secondly, I couldn't have two separate bundles that
AB> depend on different versions of an AtomParser. If they were bundles, I
AB> could have a versioned dependency so that one depended on a
AB> Virtual-Bundle: AtomService [1.0.0,2.0.0), and then another than
AB> bundle that depended on Virtual-Bundle: AtomService [2.0.0,3.0.0) in
AB> the same VM. The Service-based Import-Package has (in effect) a
AB> singleton version which prevents others from being loaded in the same
AB> VM. Furthermore, I could use this in such a way that one bundle used
AB> MyAtomParser, whilst another bundle used YourAtomParser, and a third
AB> that depended on the virtual bundle AtomParser and used a
AB> (deterministic preferred) version.

AB> The other assumption -- that package = a service -- isn't necessarily
AB> valid. For example, I might choose to provide interfaces for
AB> atom.AtomParser and atom.AtomGenerator. But just because they happen
AB> to be in the same package, it doesn't necessarily mean that they
AB> should be co-deployed. Using Import-Package/Export-Package, how would
AB> clients necessarily know which (sub)set of classes are used? On the
AB> other hand, I could provide two bundles which had the same package,
AB> and define dependencies on each of those bundles.

AB> That's why I suggested the idea of virtual bundles. They allow the
AB> same functionality as services, but without the potential problems.

AB> Alex.


-- 
Peter Kriens                              Tel +33870447986
9C, Avenue St. Drézéry                    AOL,Yahoo: pkriens
34160 Beaulieu, France                    ICQ 255570717
Skype pkriens                             Fax +1 8153772599