bundle hasn't imported. It's the second kind of reflection that causes the majority of
reflection-related problems in OSG i.
When a Java program dynamically loads a class by name, rather than by referencing a
type during normal execution, this is another form of reflection. The program is
inspecting its classpath for a particular class that can then be loaded and used to affect
its operation. In principle, there's no problem with this behavior in OSG i as long as
you take into account the way OSG i classloading works. If a piece of code uses its own
classloader to try to load another class, it will only be successful if that class exists
inside the bundle or is imported from another bundle. If the class exists but is pack-
aged somewhere else, then the class will fail to load.
This classloading model isn't dissimilar to the one from base Java, where any class
on a classloader's classpath can happily be loaded by any other class. The hitch is that
in OSG i the classpath is much smaller and more structured than the big, flat classpath
in base Java. Problems therefore arise when one class expects to be able to see
another, even though it's in a different bundle (see figure 12.3).
Because the class is loaded dynamically, there's no way to determine the depen-
dency before runtime, and you can't know what to add to your manifest. Frequently,
the class to be loaded is a private implementation class, and would not be exported
anyway. Effectively, what you get is a break in the modularity of your system, which is
why it's such a thorny problem to solve.
This sort of reflection problem isn't limited to classes. For example, library config-
uration files are usually packaged as part of applications, and then loaded reflectively
Figure 12.3 Unlike compile-time dependencies (solid lines), reflective dependencies (dashed lines) may
not be explicitly declared in bundle manifests. This won't cause problems for JARs, which have little dis-
tinction between internals and externals, but it can cause runtime failures for bundles.