Java Reference
In-Depth Information
import
javax.servlet
version="2.4.0"
import
javax.servlet
version="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
export
javax.servlet
version="2.3.0"
Figure 2.22
Consistent dependency resolution of HTTP service and client bundles
Consider the servlet parameter in the
HTTPService.registerServlet()
method.
Which version of
javax.servlet
is it? Because the
HTTP
service bundle is wired to the
Servlet
API
bundle, its parameter type is version
2.3.0
of
javax.servlet.Servlet
.
When the
HTTP
client bundle tries to invoke
HTTPService.registerServlet()
,
which version of
javax.servlet.Servlet
is the instance it passes? Because it's wired
to the Tomcat bundle, it creates a 2.4.0 instance of
javax.servlet.Servlet
. The class
spaces of the
HTTP
service and client bundles aren't consistent; two different versions
of
javax.servlet
are reachable from both. At execution time, this results in class cast
exceptions when the
HTTP
service and client bundles interact. What went wrong?
The framework made the best choices at the time it resolved the bundle depen-
dencies; but due to the incremental nature of the resolve process, it couldn't make the
best overall choice. If you install all four bundles together, the framework resolves the
dependencies in a consistent way using its existing rules. Figure 2.22 shows the depen-
dency resolution when all four bundles are resolved together.
Because only one version of
javax.servlet
is in use, you know the class spaces of
the
HTTP
service and client bundles are consistent, allowing them to interact without
issue. But is this a general remedy to class-space inconsistencies? Unfortunately, it
isn't, as you'll see in chapter 3, because
OSG
i allows you to dynamically install and
uninstall bundles at any time. Moreover, inconsistent class spaces don't only result
from incremental resolving of dependencies. It's also possible to resolve a static set of
bundles into inconsistent class spaces due to inconsistent constraints. For example,
imagine that the
HTTP
service bundle requires precisely version 2.3.0 of
javax.
servlet
, whereas the client bundle requires precisely version 2.4.0. These constraints
are clearly inconsistent, but the framework will happily resolve the example bun-
dles given the current set of dependency resolution rules. Why doesn't it detect
this inconsistency?
INTER- VS. INTRA-BUNDLE DEPENDENCIES
The difficulty is that
Export-Package
and
Import-Package
only capture inter-bundle
dependencies, but class-space consistency conflicts result from intra-bundle dependen-
cies. Recall the
org.osgi.service.http.HttpService
interface; its
register-
Servlet()
method takes a parameter of type
javax.servlet.Servlet
, which means
org.osgi.service.http
uses
javax.servlet
. Figure 2.23 shows this intra-bundle
uses
relationship between the
HTTP
service bundle's exported and imported packages.