I need to define a ClassLoader that dynamically reloads certain classes from their respective classfiles. The reason for this is that the classes are changed since runtime started.
Currently I have a classloader than can load one class from its file. What I need further is load all classes that this one classes depends on and that are in the list of changed classes.
Simply explained, I have a ClassLoader
class that overrides the loadClass
method to load the changed classfile when the required class is in the list. Otherwise, it loads the class using the default (parent) classloader.
Is it possible to also (re)load the classes that are in the class definition from the primarily loaded class using the same classloader?
So, a simple example
Class A {
static method() {
B b = new B();
C c = new C();
// do something with B and C
}
}
Class B {
public X x = new X();
}
When I load class A
with MyCustomClassLoader
, I hand it a list of classes, containing A
and C
f.e. because I know the classfiles (the bin/A.class
) of these classes have been changed. So, it should manually load the file from class A
, and when loading B
and C
, it should check if they are in the list of changed classes. When they are not, they can be loaded using the default classloader, otherwise it will do the same as with A
, recursively (so also checking classes that B
depends on).
I have the loading from file working, but not the recursion. I also know that this method does not override the Java new
operator globally. But I only need to run one changed class, but with it's dependencies also changed.
EDIT:
Note that this is not achievable using Instrumentation. The documentation for it cites the following, both for retransformClasses()
as for redefineClasses()
.
The retransformation may change method bodies, the constant pool and attributes. The retransformation must not add, remove or rename fields or methods, change the signatures of methods, or change inheritance. These restrictions maybe be lifted in future versions.
So I made a working agent to change method bodies, but only when I noticed it crashed on method creation or deletion, I found this piece of text.