JNI Warnings in OpenJDK 8 from JVM (original) (raw)

Adam Retter adam.retter at googlemail.com
Tue Feb 21 17:06:37 UTC 2017


Hi there,

I have been working on RocksJava (https://github.com/facebook/rocksdb) which is a combination of C++ JNI and Java 7.

When running this (make jcheck) with the java argument -Xcheck:jni on the Java 8 VM, we noticed lots of warnings along the lines of:

WARNING in native method: JNI call made without checking exceptions when required to from CallObjectMethod WARNING in native method: JNI call made without checking exceptions when required to from CallVoidMethod WARNING in native method: JNI call made without checking exceptions when required to from CallStaticVoidMethod ...

We modified our code to call env->ExceptionCheck() appropriately (in this branch: https://github.com/adamretter/rocksdb/tree/java8), and the vast majority of these warnings have disappeared. However we do still seem to be getting several warnings (3 distinct warnings repeated), these if I am not mistaken are actually being omitted from code within the JVM itself rather than RocksJava code. The warnings with traces look like:

WARNING in native method: JNI call made without checking exceptions when required to from CallStaticVoidMethod at java.lang.Class.isInstance(Native Method) at org.junit.runners.model.TestClass.getAnnotatedFieldValues(TestClass.java:231) at org.junit.runners.ParentRunner.classRules(ParentRunner.java:255) at org.junit.runners.ParentRunner.withClassRules(ParentRunner.java:244) at org.junit.runners.ParentRunner.classBlock(ParentRunner.java:194) at org.junit.runners.ParentRunner.run(ParentRunner.java:362) at org.junit.runners.Suite.runChild(Suite.java:128) at org.junit.runners.Suite.runChild(Suite.java:27) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at org.junit.runner.JUnitCore.run(JUnitCore.java:115) at org.junit.runner.JUnitCore.run(JUnitCore.java:105) at org.junit.runner.JUnitCore.run(JUnitCore.java:94) at org.rocksdb.test.RocksJunitRunner.main(RocksJunitRunner.java:61)

WARNING in native method: JNI call made without checking exceptions when required to from CallStaticVoidMethod at java.lang.Class.getSuperclass(Native Method) at sun.reflect.Reflection.isSubclassOf(Reflection.java:247) at sun.reflect.ReflectionFactory.newConstructorAccessor(ReflectionFactory.java:194) at java.lang.reflect.Constructor.acquireConstructorAccessor(Constructor.java:460) at java.lang.reflect.Constructor.newInstance(Constructor.java:420) at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217) at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runners.Suite.runChild(Suite.java:128) at org.junit.runners.Suite.runChild(Suite.java:27) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at org.junit.runner.JUnitCore.run(JUnitCore.java:115) at org.junit.runner.JUnitCore.run(JUnitCore.java:105) at org.junit.runner.JUnitCore.run(JUnitCore.java:94) at org.rocksdb.test.RocksJunitRunner.main(RocksJunitRunner.java:61)

WARNING in native method: JNI call made without checking exceptions when required to from CallStaticVoidMethod at java.lang.ClassLoader.findBootstrapClass(Native Method) at java.lang.ClassLoader.findBootstrapClassOrNull(ClassLoader.java:1015) at java.lang.ClassLoader.loadClass(ClassLoader.java:413)

It seems I am not the only developer noticing this unexpected behaviour with Java 8, here is a bug report for DropBox - https://github.com/dropbox/djinni/issues/152#issuecomment-157220326

The test cases I have collected that reproduce some of these warnings (weirdly I struggled to reproduce exactly the warnings I see from RocksJava) look like:

Test Case 1

$ echo 'public class Foo { public static void main(String[] args) throws Exception { } }' > Foo.java $ javac Foo.java $ java -Xcheck:jni Foo

WARNING in native method: JNI call made without checking exceptions when required to from CallStaticObjectMethod WARNING in native method: JNI call made without checking exceptions when required to from CallObjectMethod

Test Case 2

$ echo 'public class Foo2 { public static void main(String[] args) throws Exception { System.runFinalization(); System.runFinalization(); } }' > Foo2.java $ javac Foo2.java $ java -Xcheck:jni Foo2

WARNING in native method: JNI call made without checking exceptions when required to from CallStaticObjectMethod WARNING in native method: JNI call made without checking exceptions when required to from CallObjectMethod WARNING in native method: JNI call made without checking exceptions when required to from CallStaticVoidMethod at java.lang.Runtime.runFinalization0(Native Method) at java.lang.Runtime.runFinalization(Runtime.java:712) at java.lang.System.runFinalization(System.java:1015) at Foo.main(Foo.java:1)

NOTE - you need the System.runFinalization(); twice to cause the last warning.

Test Case 3

$ echo 'import java.net.NetworkInterface; public class Foo3 { public static void main(String[] args) throws Exception { NetworkInterface.getNetworkInterfaces(); } }' > Foo3.java $ javac Foo3.java $ java -Xcheck:jni Foo3

WARNING in native method: JNI call made without checking exceptions when required to from CallStaticObjectMethod WARNING in native method: JNI call made without checking exceptions when required to from CallObjectMethod WARNING: JNI local refs: 33, exceeds capacity: 32 at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at java.net.DefaultInterface.chooseDefaultInterface(DefaultInterface.java:67) at java.net.DefaultInterface.(DefaultInterface.java:46) at java.net.NetworkInterface.(NetworkInterface.java:65) at Foo3.main(Foo3.java:1) WARNING: JNI local refs: 33, exceeds capacity: 32 at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at Foo3.main(Foo3.java:1)

I have searched the OpenJDK and OracleJDK bug trackers but could not find an issue that quite covers this. For reference I have tested all of the above on Oracle JDK 1.8.0_121-b13 and Azul Zulu OpenJDK 8.20.0.5-jdk8.0.121 on Apple macOS 10.12.3.

I would be interested to find out more about what is causing this issue and how to resolve it.

Thanks Adam.

-- Adam Retter

skype: adam.retter tweet: adamretter http://www.adamretter.org.uk



More information about the hotspot-dev mailing list