Java Reference
In-Depth Information
These issues typically show up in libraries that use their own plug-in model or try to
manage their own modularity. In normal Java, it's perfectly acceptable to do this sort
of thing, but in OSG i it competes with the inherent modularity of the framework. This
is the cause of many of the problems that libraries have when moved into OSG i for the
first time.
Given that you've gone to so much trouble getting your library JAR packaged as an
OSG i bundle, it would be rather silly not to use it because of the problems that you might
encounter, but it would be good to know what some of the common problems are. One
of the most common problems you encounter when moving to OSG i comes from the dif-
ferent classloading model that OSG i has, and how it interferes with reflection.
12.2.1
Reflection in OSGi
Reflection is a commonly used pattern in Java that aims to provide a degree of modu-
larity in the code. You may remember that we introduced reflection as a poor modu-
larity implementation all the way back in chapter 1! Given that it has been such a long
time since we last covered reflection, it's worth a quick recap.
Generally the term reflection is used to describe the concept of a computer program
looking inside itself , known as introspection , and modifying its behavior or operation as a
result. In Java, this sort of reflection falls into two camps:
Locating and calling methods on a known class dynamically
Locating and loading classes that were not available at compilation time, or
configuration files
When Java developers talk about reflection, they're usually referring to the first
option, where methods can be located and invoked without a compilation depen-
dency. The main reason for thinking of this type of reflection first is that the tools
used to do it are in the java.lang.reflect package. Fortunately, in OSG i this sort of
reflection works reasonably well. If you can get hold of an Object or Class , then all of
the standard reflection API s will work correctly because they come from the base run-
time, which is shared by all bundles, regardless of version or modularity statements.
The big problem for method-level reflection comes at the point when you try to
invoke the method or to find a particular method by specifying its arguments. If the
method only refers to types from the base runtime—for example, it has an int return
type and a java.lang.String argument—then there are no problems. If the method
has more complex types in its signature, then class space compatibility becomes a fac-
tor. When invoking the method you must have the right view of all the arguments and
return type (use types loaded by the right classloader) for things to work properly. If
you get this wrong, you'll get a rather confusing ClassCastException , which often
appears to be a failure converting a type into itself.
This problem sounds serious, but it isn't as bad as you might think. It's compara-
tively rare for bundles to be able to get hold of classes that they don't share a class
space with, although you may occasionally find that some methods refer to types your
Search WWH ::




Custom Search