[英]Alternatives to getDeclaredMethods / getDeclaredFields / getConstructors
由於在上述方法中調用了Reflection.getCallerClass,因此在調用getDeclaredMethods / getDeclaredFields / getConstructors時會收到AV。
我通過JNI從Delphi應用程序創建了一個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,因為預期值已被刪除。
你的方法看似正確。 問題是你在方法中關於ClassLoader c1參數傳遞了什么? 這需要使用與您嘗試內省的類相同的VM中的類生成。 任何課程都可以。 如果你有這樣的類,你可以在它的構造函數中使用該類獲得正確的ClassLoader。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.