I have difficulty in using a generated bytecode class which is loaded by Unsafe.defineAnonymousClass()
. I am wondering how to use an object of anonymous class to initiliaze another class (or anonymous class).
Take an example class Callee below for example, its constructor accepts Callee2 as parameter.
Class Callee{
Callee2 _call2;
public Callee(Callee2 callee2){
...
}
}
During runtime, I generated new classes for both Callee2 and Callee, and both new classes are loaded by Unsafe.defineAnonymousClass()
. For new Callee, the constructor is also changed to be:
public test.code.jit.asm.simple.Callee(test.code.jit.asm.simple.Callee2.1506553666);
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=2
0: aload_0
1: invokespecial #65 // Method java/lang/Object."<init>":()V
....
8: return
while the generated class name of Callee2 is:
class test.code.jit.asm.simple.Callee2/1506553666
I created an instance of `Callee2/1506553666' and want to create instance of new Callee with it, but fail:
newCls.getConstructor(args).newInstance(objs);
where
args = [class test.code.jit.asm.simple.Callee2/1506553666]
and
objs= [test.code.jit.asm.simple.Callee2/1506553666@39b0a038]
The args[0] is meanless as this class is loaded by anonymous loader (Anonymous classes are not referenced by any class loaders). So it really puzzles me how to pass objects in objs array to a method invocation..
The exception occurs on the invocation of getConstructor (args) with message:
java.lang.NoClassDefFoundError: test/code/jit/asm/simple/Callee2/1506553666
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2483)
at java.lang.Class.getConstructor0(Class.java:2793)
at java.lang.Class.getConstructor(Class.java:1708)
at code.jit.asm.util.ReflectionUtil.adapt2GeneratedObject(ReflectionUtil.java:36)
at code.jit.asm.services.BytecodeGenerator.generator(BytecodeGenerator.java:164)
The exception is clearly for me since the anonymous class is transient to any classloader. But in my case, I do need initialize the new Callee (also anonymous class) by new Callee2 instance (The bytecodes in Callee's constructor will reads Callee2's field members), so is there any workaround to pass new callee2 instance for the new callee's constructor?