Java Reference
In-Depth Information
import
javax.servlet
version="2.3.0"
import
javax.servlet
version="[2.3.0,2.3.0]"
import
org.osgi.service.http
Tomcat
HTTP
client
HTTP
service
Servlet
API
export
javax.servlet
version="2.4.0"
export
org.osgi.service.http
uses: ="javax.servlet"
export
javax.servlet
version="2.3.0"
Figure 2.25
Uses
constraints guide dependency resolution.
For the incremental case, the framework can now detect inconsistencies in the class
spaces, and resolution fails when you try to use the client bundle. Early detection is
better than errors at execution time, because it alerts you to inconsistencies in the
deployed set of bundles. In the next chapter, you'll learn how to cause the framework
to re-resolve the bundle dependencies to remedy this situation.
You can further modify the example, to illustrate how
uses
constraints help find
proper dependency resolutions. Assume the
HTTP
service bundle imports precisely
version 2.3.0 of
javax.servlet
, but the client imports version 2.3.0 or greater. Typi-
cally, the framework tries to select the highest version of a package to resolve a depen-
dency; but due to the
uses
constraint, the framework ends up selecting a lower
version instead, as shown in figure 2.25.
If you look at the class space of the
HTTP
client, you can see how the framework ends
up with this solution. The
HTTP
client's class space contains both
javax.servlet
and
org.osgi.service.http
, because it imports these packages. From the perspective of
the
HTTP
client bundle, it can use either version 2.4.0 or 2.3.0 of
javax.servlet
, but
the framework has only one choice for
org.osgi.service.http
. Because
org.osgi.
service.http
from the
HTTP
service bundle uses
javax.servlet
, the framework must
choose the same
javax.servlet
package for any clients. Because the
HTTP
service
bundle can only use version 2.3.0 of
javax.servlet
, this eliminates the Tomcat bundle
as a possibility for the client bundle. The end result is a consistent class space where
a lower version of a needed package is correctly selected even though a higher version
is available.
ODDS AND ENDS OF USES CONSTRAINTS
Let's finish the discussion of
uses
constraints by touching on some final points. First,
uses
constraints are
transitive
, which means that if a given bundle exports package
foo
that uses imported package
bar
, and the selected exporter of
bar
uses package
baz
,
then the associated class space for a bundle importing
foo
is constrained to have the
same providers for both
bar
and
baz
, if they're used at all.
Also, even though
uses
constraints are important to capture, you don't want to cre-
ate blanket
uses
constraints, because doing so overly constrains dependency resolu-
tion. The framework has more leeway when resolving dependency on packages not
listed in
uses
constraints, which is necessary to support side-by-side versions. For exam-
ple, in larger applications, it isn't uncommon for independently developed subsystems