Java Reference
In-Depth Information
4
The environment queries the repository and finds one match. Even though
bundle
B
at version 1.0.0 and at version 1.1.0 both look like possible matches,
the mandatory directive on version 1.1.0 of
B
means that the requirement
doesn't match (because it doesn't specify
type=old
). Because of this, the repos-
itory returns
fancyfoods.pkg
exported at version 1.1 from
B
at version 1.0.0.
5
Neither
A
nor
B
has any further requirements. The resolver continues to pro-
cess the
Test
bundle.
6
The resolver queries the environment for the second package import from the
Test
bundle. The environment has no local matches and queries the reposi-
tory, which also returns no matches because there are no bundles exporting the
fancyfoods.z
package. Rather than fail the resolution at this stage, the resolver
determines that the import is optional and doesn't need to be satisfied for this
resolution to be valid.
7
The resolver reports that the
Test
bundle can be successfully resolved, and that
it requires both bundle
A
at version 1.0.0 and bundle
B
at version 1.0.0 to do so.
After you've determined that the necessary bundles required to make
Test
resolve are
A
and
B
at version 1.0.0, then the provisioner can ask the repository where the bundles
are located and download them. If
Test
were the
core content
of an application, then
you'd now have successfully determined the shared content you need to deploy it!
EXPORT-PACKAGE AND THE USES CLAUSE
Packages have a rather special place in
OSG
i because they represent the unit of modu-
larity. The problem with Java packages, however, is that they aren't particularly well-
defined units. On one level, a package is easy to define: every class declares which
package it's in. But overlaps between packages exist. Methods on an interface in one
package can accept parameters, or return things, that are declared in another pack-
age. This causes a problem for you in
OSG
i.
The identity of a class is determined by two things: its fully qualified name and the
ClassLoader
that loaded it. Because each bundle has its own classloader, but also
imports classes from other bundles, it's possible that a class will exist more than once in
a framework, but none of them will be the same class! Normally this isn't a problem,
because the resolver ensures that you're only wired to a consistent set of bundles, but
what if one of the packages you imported returned you an object from a different pack-
age? You would need to be certain that your view of that object was the same as the one
from the imported package. If it wasn't, you would get a
ClassCastException
!
This is where the
uses
clause comes in. The
uses
directive can be applied to
almost any header, but it's most often applied to
Export-Package
entries. It tells the
framework about the other packages that are
used
by the exported package. This may
mean that the exported package has method parameters or return values from those
packages, or that they're used internally by classes in the package in a way that might
cause problems. The directive instructs the resolver that when someone imports this
package, the user
must
share the same class space for
all
of the packages in the
uses
directive, as shown in listing 7.3.