Java Reference
In-Depth Information
classloading, using the thread context
ClassLoader
in
OSG
i is an attempt to break the
modularity rules built into the system. As a result, the consequences for using it are typ-
ically bad.
12.2.3
META-INF services
The awkwardness of reflection and the trickiness of the thread context
ClassLoader
compound one another if you need to adapt a
JAR
that uses
META-INF
services to run
in an
OSG
i environment. Many libraries use this pattern to supply implementations of
an interface without tightly coupling consumers to the implementation class. The way
it works is that a
ServiceLoader
searches all text files in
META-INF
/services folders.
Files must be named after interfaces and contain the name of an implementation
class. We discussed this factory system in section 1.2.4, and concluded it was limited
compared to
OSG
i services. Nonetheless, it's a popular pattern, and chances are you'll
have to handle
JAR
s that use it.
Normally, the
ServiceLoader
searches the class space for resources in the
META-
INF
/services folder. As you saw in section 12.2.1, any
JAR
wanting to expose this file
must cheat and export a pseudo-package called
META-INF/services
. But the
Ser-
viceLoader
can only be wired to one
META-INF/services
package
at a time, so the
cheat clearly won't scale well!
As if that wasn't enough of a hurdle, the
ServiceLoader
uses the thread context
ClassLoader
to look for and load resources. We've already seen that this classloader is
undefined in
OSG
i. Even if one is available, it's unlikely to be able to see internal
implementation classes, unless these classes are explicitly exported from the providing
bundle. It goes without saying that exporting implementation packages is an
OSG
i
anti-pattern, and completely subverts the encapsulation the
META-INF
services pattern
was trying to achieve!
The good news is that enterprise
OSG
i has devised a way of making things work
without requiring pseudo-packages and exported internals. The Service Loader Medi-
ation Specification allows
META-INF
services to be made available through the Service
Registry with relatively non-invasive manifest changes. All that's required is an indica-
tion to the
OSG
i service loader extender that
META-INF
services should be processed.
For example, to expose a service for the
shop.Bananas
interface, the following should
be added to a bundle manifest:
Require-Capability: osgi.extender;
filter:="(osgi.extender=osgi.
serviceloader.registrar)"
Provide-Capability: osgi.serviceloader; osgi.serviceloader=shop.Bananas
JAR
s that use the
ServiceLoader.load()
API
can opt to have those calls magically
transformed into ones that will have the correct visibility of required implementations
in
OSG
i by requesting processing with a manifest header, as follows:
Require-Capability: osgi.extender;
filter:="(osgi.extender=osgi.
serviceloader.processor)"