Java Reference
In-Depth Information
you no longer see any exceptions or linkage errors:
SPOKE org.foo.spoke.no_uses_constraints RECEIVED Testing Testing 1, 2, 3...
You just saw how
uses
constraints can help you avoid inconsistent class spaces and odd
linkage errors, but what happens if they can't be satisfied? You can find out by tweaking
the version range for
org.foo.hub
in the spoke bundle. By using a range of
[2.0, 3.0)
,
you leave only one matching exporter of
org.foo.hub
: the spoke bundle itself. But this
breaks the
uses
constraints on the
SPI
package exported from the main
API
bundle,
because it has a range of
[1.0, 2.0)
for
org.foo.hub
. These two ranges are incompat-
ible: there's no way you can find a solution that satisfies both. The fifth example dem-
onstrates the result:
$
./chapter08/classloading/PICK_EXAMPLE 5
Error starting framework: org.osgi.framework.BundleException:
Unable to resolve due to constraint violation.
Unfortunately, the framework exception doesn't tell you which constraint failed or
why. Determining why a solution wasn't found without help from the framework can
be time consuming, because the search space of potential solutions can be large.
Fortunately, Equinox has a
diag
command to explain which constraints were left
unsatisfied. With Felix, you can add more details to the original exception by enabling
debug logging.
For example, if you change the last line in the
PICK_EXAMPLE
script to
java "-Dfelix.log.level=4" -jar launcher.jar bundles
this enables Felix debug logging, which prints the following message before the
exception is thrown:
$
./chapter08/classloading/PICK_EXAMPLE 5
DEBUG: Constraint violation for 1.0 detected;
module can see org.foo.hub from [1.0] and org.foo.hub from [2.0]
The message tells you the unsatisfied constraint is related to the
org.foo.hub
pack-
age. It also gives you the identifiers of the bundles involved. This is another reason
why it's a good idea to use
uses
constraints. Without them, you'd have to debug con-
fusing class-loading problems with no support from the framework. By using
uses
constraints, you can avoid linkage errors to begin with and help the framework
explain why certain sets of bundles aren't compatible. But it can only do this if the
constraints are valid and consistent, which is why we recommend you always use a tool
to compute them, such as bnd.
So far, we've concentrated on what happens when your bundle metadata is wrong;
but even a perfect manifest doesn't always guarantee success. Certain coding practices
common to legacy code can cause problems in
OSG
i because they assume a flat, static
class path. One practice worth avoiding is the use of
Class.forName()
to dynamically
load code.