Java 给定一个类文件,如何检测它是否使用JNI?

Java 给定一个类文件,如何检测它是否使用JNI?,java,java-native-interface,bytecode,.class-file,javap,Java,Java Native Interface,Bytecode,.class File,Javap,我有一些只包含类文件的Java基准测试 我想找出哪些基准有JNI调用 我想在javap-c的帮助下,也许可以从字节码级别实现这一点,但不确定 有什么想法吗?如果允许加载该类,可以使用反射: Class<?> clazz = ... List<Method> nativeMethods = new ArrayList<>(); for (Method m : clazz.getDelcaredMethods()) { if(Modifier.isNati

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

我想找出哪些基准有JNI调用

我想在javap-c的帮助下,也许可以从字节码级别实现这一点,但不确定


有什么想法吗?

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

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

从最初的问题来看,不清楚您是否希望以编程方式查找本机JNI方法。使用javap,您可以使用如下内容:

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

这是按照您描述的思路进行的:

javah  [options] <classes> -d <dir>
grep -r "JNIEXPORT" <dir>
每一行输出都将使用其JNI导出名称标识本机方法


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

感谢所有的答案

我发现一个简单的方法如下:

java-verbose:jni-jarfoo.jar

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


以下是HotSpot中有关此选项的详细信息:

这可能会导致误报。@锑会怎么做?例如,如果其中一个方法的名称中有“native”。@锑我认为很容易看出哪些方法是,哪些不是。当您执行该行时,您将获得该方法的整个签名,并且很容易发现误报。但是如果您遵循EJP的建议,您将不会得到任何结果。当然,假设类文件是未修改的Java。如果它们是模糊的或不是最初从Java编译的,那么您可能有一个名为native的方法。同样,javap也有可能在试图解析类文件时崩溃。我想这不是什么大问题,除非你正在做。