Average Joe
Average Joe

Reputation: 683

Classloader delegation model

I have a simple custom ClassLoader

class CustomLoader extends ClassLoader {
    @Override
    protected Class findClass(String name) throws ClassNotFoundException {
        System.out.println("In the custom loader");
        throw new ClassNotFoundException();
    }
}

And here is a code I'm trying to use the loader in:

public static void main(String... str) throws ClassNotFoundException {
        CustomLoader loader = new CustomLoader();
        Class<?> cls = loader.loadClass("java.awt.Color");

        System.out.println(cls);
        System.out.println(cls.getClassLoader());
}

The result is pretty expectable:

class java.awt.Color
null

In most articles you can see that when you call loadClass on your custom loader, first it tries to find the class in its cache. If it can't find it, it calls the loadClass method from a parent loader (in this case - Application loader). And so to the bootstrap loader. After that, if the bootstrap loader can't find the class in its cache, it tries to find it in respective sources. If the loader can't find it, the child loader tries to find and so on to the custom loader.

If you look at classloader implementation, you will see that it simply calls the findClass method. But given that I use a custom loader and that java has a polymorphism, wherever parent loaders call findClass they call my method, right?

At the same time, it's said that java doesn't load all the classes at once and only when it's necesarry.

As you can see, we didn't see any class cast exception and in fact my overriden method wasn't even called. Which means the bootstrap loader found it the class Color.

The question is where is my mistake? If java doesn't load all the classes from java... packages when jvm starts, it would not find the class Color in cache and it would call my overriden method.

(the class Color wasn't used in any other place in the code)

Upvotes: 4

Views: 237

Answers (1)

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 136062

According to ClassLoader API the default delegation model works this way

When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself.

This delegation model is implemented in ClassLoader.loadClass method, to change it you should override loadClass method instead of findClass

Upvotes: 3

Related Questions