Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split packages in plain java

OSGi has a problem with split packages, i.e. same package but hosted in multiple bundles.

Are there any edge cases that split packages might pose problems in plain java (without OSGi) ?

Just curious.

like image 456
ashitaka Avatar asked Jan 02 '09 07:01

ashitaka


2 Answers

Where split packages come from

Split packages (in OSGi) occur when the manifest header Require-Bundle is used (as it is, I believe, in Eclipse's manifests). Require-Bundle names other bundles which are used to search for classes (if the package isn't Imported). The search happens before the bundles own classpath is searched. This allows the classes for a single package to be loaded from the exports of multiple bundles (probably distinct jars).

The OSGi spec (4.1) section 3.13 describes Require-Bundle and has a long list of (unexpected) consequences of using this header (ought this header be deprecated?), one section of which is devoted to split packages. Some of these consequences are bizarre (and rather OSGi-specific) but most are avoided if you understand one thing:

  • if a class (in a package) is provided by more than one bundle then you are in trouble.

If the package pieces are disjoint, then all should be well, except that you might not have the classes visible everywhere and package visibility members might appear to be private if viewed from a "wrong" part of a split package.

[Of course that's too simple—multiple versions of packages can be installed—but from the application's point of view at any one time all classes from a package should be sourced from a single module.]

What happens in 'standard Java'

In standard Java, without fancy class-loaders, you have a classpath, and the order of searching of jars (and directories) for classes to load is fixed and well-defined: what you get is what you get. (But then, we give up manageable modularity.)

Sure, you can have split packages—it's quite common in fact—and it is an indication of poor modularity. The symptoms can be obscure compile/build-time errors, but in the case of multiple class implementations (one over-rides the rest in a single class-path) it most often produces obscure run-time behaviour, owing to subtly-different semantics.

If you are lucky you end up looking at the wrong code—without realising it—and asking yourself "but how can that possibly be doing that?"
If you are unlucky you are looking at the right code and asking exactly the same thing—because something else was producing unexpected answers.

This is not entirely unlike the old database adage: "if you record the same piece of information in two places, pretty soon it won't be the same anymore". Our problem is that 'pretty soon' isn't normally soon enough.

like image 87
Steve Powell Avatar answered Oct 09 '22 03:10

Steve Powell


For OSGi packages in different bundles are different, regardless of their name, because each bundle uses its own class loader. It is not a problem but a feature, to ensure encapsulation of bundles.

So in plain Java this is normally not a problem, until you start using some framework that uses class loaders. That is typically the case when components are loaded.

like image 39
starblue Avatar answered Oct 09 '22 03:10

starblue