Java: A platform for platforms
Sun's reorg may seem promising to shareholders but it's also a scramble for position. The question now is whether Sun can, or wants to, maintain its hold on Java technology. Especially with enterprise leaders like SpringSource and RedHat investing heavily in Java's future as a platform for platforms

Also see:

Discuss: Tim Bray on 'What Sun Should Do'

Featured Whitepapers
Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

The basics of Java class loaders

The fundamentals of this key component of the Java architecture

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Page 2 of 5

A user class loader gets the chance to load a class before the primordial class loader does. Because of this, it can load the class implementation data from some alternate source, which is how the AppletClassLoader can load classes using the HTTP protocol.

Building a SimpleClassLoader

A class loader starts by being a subclass of java.lang.ClassLoader. The only abstract method that must be implemented is loadClass(). The flow of loadClass() is as follows:

  • Verify class name.
  • Check to see if the class requested has already been loaded.
  • Check to see if the class is a "system" class.
  • Attempt to fetch the class from this class loader's repository.
  • Define the class for the VM.
  • Resolve the class.
  • Return the class to the caller.


Some Java code that implements this flow is taken from the file SimpleClassLoader and appears as follows with descriptions about what it does interspersed with the code.

 
public synchronized Class loadClass(String className, boolean resolveIt) 
         throws ClassNotFoundException { 
         Class result; 
         byte classData[]; 
         System.out.println(" >>>>>> Load class : "+className); 
         /* Check our local cache of classes */ 
         result = (Class)classes.get(className); 
         if (result != null) { 
             System.out.println(" >>>>>> returning cached result."); 
             return result; 
} 


The code above is the first section of the loadClass method. As you can see, it takes a class name and searches a local hash table that our class loader is maintaining of classes it has already returned. It is important to keep this hash table around since you must return the same class object reference for the same class name every time you are asked for it. Otherwise the system will believe there are two different classes with the same name and will throw a ClassCastException whenever you assign an object reference between them. It's also important to keep a cache because the loadClass() method is called recursively when a class is being resolved, and you will need to return the cached result rather than chase it down for another copy.

/* Check with the primordial class loader */ 
try { 
    result = super.findSystemClass(className); 
    System.out.println(" >>>>>> returning system class (in CLASSPATH)."); 
    return result; 
    } catch (ClassNotFoundException e) { 
             System.out.println("        >>>>>> Not a system class."); 
    } 


As you can see in the code above, the next step is to check if the primordial class loader can resolve this class name. This check is essential to both the sanity and security of the system. For example, if you return your own instance of java.lang.Object to the caller, then this object will share no common superclass with any other object! The security of the system can be compromised if your class loader returned its own value of java.lang.SecurityManager, which did not have the same checks as the real one did.

 
/* Try to load it from our repository */ 
classData = getClassImplFromDataBase(className); 
if (classData == null) { 
    throw new ClassNotFoundException(); 
} 


After the initial checks, we come to the code above which is where the simple class loader gets an opportunity to load an implementation of this class. As you can see from the source code, the SimpleClassLoader has a method getClassImplFromDataBase() which in our simple example merely prefixes the directory "store\" to the class name and appends the extension ".impl". I chose this technique in the example so that there would be no question of the primordial class loader finding our class. Note that the sun.applet.AppletClassLoader prefixes the codebase URL from the HTML page where an applet lives to the name and then does an HTTP get request to fetch the bytecodes.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources
  • Doug Lea has a set of collection (container) classes that he built here.