由于在上述方法中调用了 Reflection.getCallerClass,我在调用 getDeclaredMethods / getDeclaredFields / getConstructors 时收到了 AV。
我已经从 Delphi 应用程序通过 JNI 创建了一个 Java VM。不幸的是,我发现在调用 java.lang.Class 类中的某些方法时,这些方法调用
checkMemberAccess(1, Reflection.getCallerClass(), true);
这会导致 AV,因为堆栈上没有真正的 Java 类,因为我直接调用 getDeclaredXXX 方法,以及来自 Delphi 的 JNI 调用。
为了克服 getCallerClass,我创建了一个 Java 类包装器,如下所示:
public class DelphiClassHelper {
private Field[] f;
private Method[] m;
private Constructor<?>[] c;
private static DelphiClassHelper helper;
public Field[] pGetDeclaredFields(ClassLoader cl, String ClassName) {
Class<?> AClass = null;
try {
System.out.println("Loading class: "+ClassName);
System.out.println("ClassLoader: "+cl.toString());
AClass = cl.loadClass(ClassName);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
if (AClass!=null) {
f = AClass.getDeclaredFields();
return f;
} else
return new Field[]{};
}
public static Field[] GetDeclaredFields(ClassLoader cl, String ClassName) {
helper = new DelphiClassHelper();
return helper.pGetDeclaredFields(cl, ClassName);
}
public Method[] pGetDeclaredMethods(ClassLoader cl, String ClassName) {
Class<?> AClass = null;
try {
System.out.println("Loading class: "+ClassName);
System.out.println("ClassLoader: "+cl.toString());
AClass = cl.loadClass(ClassName);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
if (AClass!=null) {
m = AClass.getDeclaredMethods();
return m;
} else
return new Method[]{};
}
public static Method[] GetDeclaredMethods(ClassLoader cl, String ClassName) {
helper = new DelphiClassHelper();
return helper.pGetDeclaredMethods(cl, ClassName);
}
public Constructor<?>[] pGetConstructors(ClassLoader cl, String ClassName) {
Class<?> AClass = null;
try {
System.out.println("Loading class: "+ClassName);
System.out.println("ClassLoader: "+cl.toString());
AClass = cl.loadClass(ClassName);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
if (AClass!=null) {
c = AClass.getConstructors();
return c;
} else
return new Constructor[]{};
}
public static Constructor<?>[] GetConstructors(ClassLoader cl, String ClassName) {
helper = new DelphiClassHelper();
return helper.pGetConstructors(cl, ClassName);
}
}
我创建上面的想法是公共静态方法创建一个Java类,然后调用实例方法pXXXX,然后调用方法Class.getDeclaredMethods,getDeclaredFields,getConstructors之一,这肯定会满足getCallerClass调用,因此,防止AV。
但是不,我仍然得到 AV。是否有任何其他框架可以提供 getDeclaredXXXX 方法提供的信息,或者是否有解决 getCallerClass 要求的方法,例如在堆栈上创建一个可以满足 Reflection.getCallerClass 调用的假类?
我的 Delphi 到 JNI 应用程序的其他部分可以工作,只要它不调用任何最终调用 Reflection.getCallerClass 的 Java 方法。
请注意,当我通过 JNI 调用创建 Java VM 时,没有适当的 SecurityManager。
更新:2014 年 1 月 24 日 AV 的原因是由于一些优化,这导致对象实例被放置在一个 CPU 寄存器中,在调用 checkMemberAccess 时该寄存器被擦除。随后,当 Delphi 运行时尝试从 CPU 寄存器中检索对象并再次使用它时,它会导致 AV,因为预期值已被丢弃。