簡體   English   中英

getDeclaredMethods / getDeclaredFields / getConstructors的替代方案

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM