JNI Warnings in OpenJDK 8 from JVM
David Holmes
david.holmes at oracle.com
Wed Feb 22 04:47:40 UTC 2017
Hi Adam,
On 22/02/2017 3:06 AM, Adam Retter wrote:
> 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)
I think I need to see how main gets invoked in a thread. I suspect it is
being done by reflection. Even so the flag to say there is a
pending-"exception check" is enabled when the method returns, so we
should not be in a position where that flag should be on when we
eventually call Class.isInstance(). Unless the flag was already on, due
to the way in "main" actually gets invoked by the junit code!
David
-----
>
> 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)
> - locked <0x000000076ab00380> (a java.lang.Object)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
> - locked <0x000000076ab002d0> (a java.lang.Object)
> at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
> at org.junit.runner.notification.RunNotifier.fireTestRunFinished(RunNotifier.java:100)
> at org.junit.runner.JUnitCore.run(JUnitCore.java:138)
> 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)
>
>
> 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.<clinit>(DefaultInterface.java:46)
> at java.net.NetworkInterface.<clinit>(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.
>
>
More information about the hotspot-dev
mailing list