Java Reference
In-Depth Information
content of the spoke implementation bundle; the
API
, hub extender, and test bundles
remain exactly the same. By the end of this section, you should understand which
class-loading issues can arise from simple changes in content and metadata and how
you can diagnose and fix them when something goes wrong.
8.2.1
ClassNotFoundException vs. NoClassDefFoundError
The first thing you should do when debugging a class-loading exception is look and
see if the exception is
ClassNotFoundException
or
NoClassDefFoundError
. A subtle
difference between these two types will help you understand why the exception
occurred and how to fix it.
CLASSNOTFOUNDEXCEPTION
A
ClassNotFoundException
means the reporting class loader wasn't able to find or
load the initial named class, either by itself or by delegating to other class loaders.
This could occur in a Java application for three main reasons:
There's a typo in the name passed to the class loader (common).
■
The class loader (and its peers) have no knowledge of the named class.
■
The named class is available, but it isn't visible to the calling code.
■
The third case, visibility, is where things get interesting. You know all about
public
,
protected
, and
private
access; but how many of you know what
package private
means?
Package-private
classes are those without any access modifier before their
class
keyword. Their visibility rules are unique: in addition to only being visible to classes
from the same package, they're also only visible to classes from the same
class loader
.
Most Java programs have a single application class loader, so this last rule hardly ever
comes up.
OSG
i applications contain multiple class loaders, but as long as each pack-
age is loaded by only one class loader, it's effectively the same as before. The real prob-
lem arises with split packages (see section 5.3), which span several class loaders.
Package-private classes from a split package in one bundle aren't visible to fellow
classes in other bundles. This can lead to
ClassNotFoundException
s or
Illegal-
AccessException
s that wouldn't happen with a single application class loader.
Figure 8.10 shows three different package-private scenarios: one classic and two
involving split packages. Each scenario has subtly different class visibility.
To see a common
ClassNotFoundException
situation, run the following example:
$
./chapter08/classloading/PICK_EXAMPLE 1
This builds and deploys a spoke bundle with incorrect extender metadata concerning
its implementation class: it lists the name as
MySpokeImpl
instead of
SpokeImpl
. This is
an easy mistake to make in applications configured with
XML
or property files because
of the lack of type safety. The resulting exception gives the name of the missing class:
java.lang.ClassNotFoundException: org.foo.spoke.MySpokeImpl
You should use this information to check if the name is correct, the class is visible, and
the package containing the class is either imported or contained inside the bundle.