Java Reference
In-Depth Information
In order for the code change to be effective, you have to get hold of a class-
loader that can load the resources you need it to. If you can identify a class with visi-
bility of the resources, then the classloader of the owning bundle is a good bet.
Bundles don't directly expose their classloader, but a call like
ClassThatCanSee-
Resources.class.getClassLoader()
will return a suitable classloader. If you have
a bundle but no class, you can write a facade classloader that delegates to the
bundle.loadClass()
and
bundle.loadResource()
methods. As long as the bundle
contains some classes, you can instead use
bundle.getEntries()
to introspect
the bundle contents and find an arbitrary class name, and then use
bundle
.loadClass().getClassLoader()
to get the classloader. Both of these methods are
fragile and require caution.
The biggest problem with setting the thread context
ClassLoader
is that you can't
always be sure it will stay set. When you call out to third-party code, it's entirely possi-
ble that the first thing it does is to change, or unset, the thread context
ClassLoader
.
If it does, then you're a little stuck! All we can suggest is that if you're having thread
context
ClassLoader
issues, then this is something to try.
If setting the thread context
ClassLoader
is too invasive for your taste, you don't
have the source, aren't allowed to change the source by its license, or it doesn't work,
then all isn't lost. Another, somewhat specialized, manifest header can come to the
rescue. Given that this is the case, you may wonder why we haven't been extolling its
virtues throughout this chapter. The answer is simple: this header comes with a price.
12.3.3
DynamicImport-Packageāa saving grace?
We've spent a lot of time throughout this topic discussing the use of package imports
to achieve modularity. By correctly describing your dependencies, you gain a powerful
understanding of your application and a lot of flexibility. There has been one consis-
tent message, which is that until all of your dependencies are available, your bundle
can't be used. This statement is weakened somewhat when using the
optional
direc-
tive, which allows your bundle to start in the absence of some packages. Importantly,
the
optional
directive is an all-or-nothing deal: either your package will be wired
when your bundle resolves, or it
never
will (unless the bundle is reresolved).
DynamicImport-Package
operates like an optional import in that it won't stop your
bundle from resolving. If that was all
DynamicImport-Package
did it would be useless,
but there's an important difference. Whereas an optional import is either
wired
or
not
wired
, you can think of
DynamicImport-Package
as imports that aren't wired
yet
.
Dynamic package imports indicate to the
OSG
i framework that it should attempt to
wire the package when the bundle first attempts to load something from it. If the wir-
ing fails, then so does the attempt to load the resource. Critically, when a dynamic
import has been successfully wired, it's wired for good. At this point, a dynamic import
is no different from a normal one.
Another key difference between dynamic imports and normal imports is that
dynamic imports can be defined using wildcards, as follows. This allows a bundle to