Search code examples
javaclassloadersuperclassjava-bytecode-asm

How to load a modified superclass in Java?


  • I have a class A extends B.
  • I've created a CustomClassLoader extends ClassLoader to use defineClass(className, byte[], offset, length).
  • I've instanciate a new CustomClassLoader(Thread.currentThread().getContextClassLoader()). So the parent of my CustomClassLoader is the ClassLoader from the current thread.
  • I've modified B class using ASM framework. I've write my modified class in a .class file and use a decompiler to be sure it works. And it works.
  • I've added modified B class to my CustomClassLoader
  • I've set the Thread.currentThread().setContextClassLoader() with my CustomClassLoader.
  • I've load A using Class.forName(String, true, the CustomClassLoader).
  • But the loaded B class seems to be the orginal class.

What did I wrong ? If you need more info, a detailed topic is on my GitHub.


Solution

  • Java classloaders first search the parent classloader before looking in the child.

    The loadClass method in ClassLoader performs these tasks, in order, when called to load a class:

    1. If a class has already been loaded, it returns it.
    2. Otherwise, it delegates the search for the new class to the parent class loader.
    3. If the parent class loader does not find the class, loadClass calls the method findClass to find and load the class.

    (Understanding Extension Class Loading - Oracle)

    If you want to change that order, you need to override the loadClass method as well but there are many caveats and it's not advisable unless you understand classloading very well.

    • The easier option is to make sure that the parent class loader cannot find the original class B.