0

I have some Java benchmarks with only class files.

I would like to find which benchmarks have JNI calls.

I thought maybe this can be done from the bytecode level with the help of javap -c, but not sure.

Any ideas?

JackWM
  • 10,085
  • 22
  • 65
  • 92

4 Answers4

7

If you're allowed to load the class, you can use reflection:

Class<?> clazz = ...
List<Method> nativeMethods = new ArrayList<>();
for (Method m : clazz.getDelcaredMethods()) {
    if(Modifier.isNative(m.getModifiers())) {
        nativeMethods.add(m);
    }
}
Jeffrey
  • 44,417
  • 8
  • 90
  • 141
2

It is unclear from original question if you want to find native (JNI) methods programmatically. With javap you can use something like this:

javap -private java.awt.image.BufferedImage | grep native
Eugene Kuleshov
  • 31,461
  • 5
  • 66
  • 67
  • That might lead to false positives. – Antimony Jul 21 '13 at 20:58
  • @Antimony How would it? – Jeffrey Jul 21 '13 at 22:32
  • If one of the methods had 'native' in its name for instance. – Antimony Jul 21 '13 at 22:56
  • @Antimony I think it would be fairly easy to see which methods were and were not. When you execute that line you get the entire signature of the method, and it would be pretty easy to spot the false positives. But if you follow EJP's advice, you won't get any. – Jeffrey Jul 22 '13 at 01:45
  • Assuming of course the class files are unmodified Java. If they were obfuscated or not originally compiled from Java, then it's possible you might have a method named `native`. Then again, it's also possible for javap to just crash trying to parse the classfile. I suppose it's not a big worry unless you're doing RE. – Antimony Jul 22 '13 at 02:22
0

This works along the lines you've described:

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

Each line of output will identify a native method using its JNI export name.

However, this does not determine if the native method has been called or loaded by the JVM or even defined in a shared library. A native method only needs to be defined if it is called and even then its absence is a trappable error.

Tom Blodget
  • 20,260
  • 3
  • 39
  • 72
0

Thanks for all the answers.

I found a simple way as below:

java -verbose:jni -jar foo.jar

Basically, it prints a trace message to the console showing the JNI methods.

Here is the details about this option from HotSpot : ref

JackWM
  • 10,085
  • 22
  • 65
  • 92