Reputation: 683
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
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