Java getDeclaredMethods/getDeclaredFields/getConstructors的替代方法

Java getDeclaredMethods/getDeclaredFields/getConstructors的替代方法,java,delphi,java-native-interface,Java,Delphi,Java Native Interface,在调用getDeclaredMethods/getDeclaredFields/getConstructors时,由于在上述方法中调用了Reflection.getCallerClass,我得到了AVs 我已经从一个Delphi应用程序通过JNI创建了一个JavaVM。不幸的是,我发现在java.lang.Class类中调用某些方法时,这些方法调用 checkMemberAccess(1, Reflection.getCallerClass(), true); 这会导致一个AV,因为堆栈上没有

在调用getDeclaredMethods/getDeclaredFields/getConstructors时,由于在上述方法中调用了Reflection.getCallerClass,我得到了AVs

我已经从一个Delphi应用程序通过JNI创建了一个JavaVM。不幸的是,我发现在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);
  }

}
公共类帮助器{
私人领域[]f;
私有方法[]m;
私有构造函数[]c;
私有静态类助手;
公共字段[]pGetDeclaredFields(类加载器cl,字符串类名称){
类AClass=null;
试一试{
System.out.println(“加载类:“+ClassName”);
System.out.println(“类加载器:+cl.toString());
AClass=cl.loadClass(类名);
}catch(classnotfounde异常){
System.out.println(e.getMessage());
e、 printStackTrace();
}  
如果(AClass!=null){
f=AClass.getDeclaredFields();
返回f;
}否则
返回新字段[]{};
}
公共静态字段[]GetDeclaredFields(类加载器cl,字符串类名称){
helper=新的DelphiClassHelper();
return helper.pGetDeclaredFields(cl,ClassName);
}
公共方法[]pGetDeclaredMethods(类加载器cl,字符串类名称){
类AClass=null;
试一试{
System.out.println(“加载类:“+ClassName”);
System.out.println(“类加载器:+cl.toString());
AClass=cl.loadClass(类名);
}catch(classnotfounde异常){
System.out.println(e.getMessage());
e、 printStackTrace();
}  
如果(AClass!=null){
m=AClass.getDeclaredMethods();
返回m;
}否则
返回新方法[]{};
}
公共静态方法[]GetDeclaredMethods(类加载器cl,字符串类名称){
helper=新的DelphiClassHelper();
return helper.pGetDeclaredMethods(cl,ClassName);
}
公共构造函数[]pGetConstructors(类加载器cl,字符串类名称){
类AClass=null;
试一试{
System.out.println(“加载类:“+ClassName”);
System.out.println(“类加载器:+cl.toString());
AClass=cl.loadClass(类名);
}catch(classnotfounde异常){
System.out.println(e.getMessage());
e、 printStackTrace();
}  
如果(AClass!=null){
c=AClass.getConstructors();
返回c;
}否则
返回新构造函数[]{};
}
公共静态构造函数[]GetConstructors(类加载器cl,字符串类名称){
helper=新的DelphiClassHelper();
return helper.pGetConstructors(cl,ClassName);
}
}
我创建上述方法的想法是,公共静态方法创建一个Java类,然后调用实例方法pxxx,然后调用其中一个方法类。getDeclaredMethods、getDeclaredFields、getConstructor,这肯定会满足getCallerClass调用,从而防止AV

但是没有,我仍然有AVs。是否有其他框架可以提供getDeclaredXXXX方法提供的信息,或者是否有解决getCallerClass要求的方法,例如在堆栈上创建一个可以满足Reflection.getCallerClass调用的假类

我的Delphi到JNI应用程序的其他部分可以工作,只要它不调用任何最终调用Reflection.getCallerClass的Java方法

注意,由于我是通过JNI调用创建JavaVM的,所以没有安装SecurityManager

更新:2014年1月24日
AV的原因是由于某些优化,这导致对象的实例被放置在一个CPU寄存器中,在调用checkMemberAccess时会被擦除。随后,当Delphi运行时尝试从CPU寄存器中检索对象并再次使用它时,会导致AV,因为预期值被破坏

您的方法似乎是正确的。问题是关于方法中的ClassLoader c1参数,您传递了什么?这需要使用来自与您尝试内省的类相同的VM的类来生成。任何课程都可以。如果您有这样一个类,您可以在其构造函数中使用该类获得正确的类加载器ny。

如果您的方法被称为
getDeclaredMethods
,Java是区分大小写的?我认为当出现案例不匹配时,Java不会流行起来。对于
getDeclaredFields
etc.1,同上。代码可以编译。2.请参阅最后第二段-“其他部分…工作”您完全没有抓住评论的要点。这里没有区分大小写的问题,谢谢您的建议。您是否尝试在启动VM时覆盖所有安全策略以删除所有访问限制
java.security.policy==myOverridePolicy.policy
另外,您是否检查了从本机代码调用时
Reflection.getCallerClass()返回的内容?