我在使用Unsafe.defineAnonymousClass()
加载生成的字节码类时遇到了困难。我想知道如何使用匿名类对象来初始化另一个类(或匿名类)。
例如,以下面的Callee类为例,它的构造函数接受Callee2作为参数。
Class Callee{
Callee2 _call2;
public Callee(Callee2 callee2){
...
}
}
在运行时,我为Callee2和Callee生成了新的类,并且这些新的类都被Unsafe.defineAnonymousClass()
加载。对于新的Callee,构造函数也被更改为:
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
Callee2 生成的类名为:
class test.code.jit.asm.simple.Callee2/1506553666
我创建了一个`Callee2/1506553666`的实例,并想要使用它来创建一个新的Callee实例,但是失败了:
newCls.getConstructor(args).newInstance(objs);
需要翻译的内容:
其中args = [class test.code.jit.asm.simple.Callee2/1506553666]
,objs= [test.code.jit.asm.simple.Callee2/1506553666@39b0a038]
由于这个类是通过匿名加载器加载的(匿名类不受任何类加载器引用),所以args[0]没有意义。因此,我真的很困惑如何将objs数组中的对象传递给方法调用。
在调用getConstructor(args)时,抛出了异常,异常信息为:
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)
这个异常显然是针对于我自己的,因为匿名类对于任何类加载器都是瞬态的。但是在我的情况下,我需要通过新的Callee2实例来初始化新的Callee(Callee构造函数中的字节码将读取Callee2的字段成员),那么是否存在绕过此异常并将新的Callee2实例传递给新的Callee构造函数的方法?
Callee2
类的字节码没有正确地注入到类加载器中。这就是为什么它无法加载Calle2
类的原因。我曾经生成过动态代码(很久以前),使用编译器工具进行编译并注入,但采用了不同的方法。有关详细信息,请单击此处。 - fps