Search code examples
javasystemclassloaderurlclassloader

Java is there a way to load a class that has been already loaded by the System ClassLoader by a different one?


(Terrible Title, I know)

The best way to explain this, is that I need to load some classes that will be loaded at Runtime from a URLClassLoader, by these classes have references to instances of classes that are already loaded by the System ClassLoader and they can't be reloaded because of some other issues.

Also, I am willing to change around my code so I can load classes from a jar in the class path with the System ClassLoader, but I haven't been able to do that.


Solution

  • No. Every classloader has the bootstrap classloader as an ancestor, and trying to load a class that is already defined in a classloader will just result in use of the ancestor's version. This is intentional to prevent java.lang.Object and other intrinsics from being redefined.

    From the javadoc for ClassLoader:

    The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. 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. The virtual machine's built-in class loader, called the "bootstrap class loader", does not itself have a parent but may serve as the parent of a ClassLoader instance.

    You may be able to define a custom classloader that exposes defineClass without it being called by findClass and avoid the delegation that happens in findClass, but I would not rely on defineClass(className, bytes) working as intended on all JVMs when parent.findClass(className) exists.