【问题标题】:Given a class file, how to detect it uses JNI or not?给定一个类文件,如何检测它是否使用 JNI?
【发布时间】:2013-07-21 20:21:08
【问题描述】:

我有一些只有类文件的 Java 基准测试。

我想知道哪些基准有 JNI 调用。

我想也许这可以在javap -c 的帮助下从字节码级别完成,但不确定。

有什么想法吗?

【问题讨论】:

    标签: java java-native-interface bytecode .class-file javap


    【解决方案1】:

    如果你被允许加载类,你可以使用反射:

    Class<?> clazz = ...
    List<Method> nativeMethods = new ArrayList<>();
    for (Method m : clazz.getDelcaredMethods()) {
        if(Modifier.isNative(m.getModifiers())) {
            nativeMethods.add(m);
        }
    }
    

    【讨论】:

      【解决方案2】:

      如果您想以编程方式查找本机 (JNI) 方法,原始问题尚不清楚。使用 javap 你可以使用这样的东西:

      javap -private java.awt.image.BufferedImage | grep native
      

      【讨论】:

      • 这可能会导致误报。
      • @Antimony 会怎样?
      • 例如,如果其中一种方法的名称中包含“native”。
      • @Antimony 我认为很容易看出哪些方法是和不是。当您执行该行时,您将获得该方法的整个签名,并且很容易发现误报。但如果你听从 EJP 的建议,你将一无所获。
      • 当然假设类文件是未经修改的Java。如果它们被混淆或最初不是从 Java 编译的,那么您可能有一个名为 native 的方法。再说一次,javap 也有可能在尝试解析类文件时崩溃。我想这不是什么大问题,除非你在做 RE。
      【解决方案3】:

      这符合您所描述的路线:

      javah  [options] <classes> -d <dir>
      grep -r "JNIEXPORT" <dir>
      

      每一行输出都将使用其 JNI 导出名称来标识本机方法。

      但是,这并不能确定本机方法是否已被 JVM 调用或加载,甚至是否在共享库中定义。仅当调用本机方法时才需要定义它,即使没有它也是一个可捕获的错误。

      【讨论】:

        【解决方案4】:

        感谢您的所有回答。

        我找到了一个简单的方法如下:

        java -verbose:jni -jar foo.jar

        基本上,它会向控制台打印一条显示 JNI 方法的跟踪消息。

        以下是来自 HotSpot 的有关此选项的详细信息:ref

        【讨论】:

          猜你喜欢
          • 2016-12-20
          • 2012-12-26
          • 1970-01-01
          • 1970-01-01
          • 2017-11-02
          • 2019-08-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多