The -Xcheck:jni option is useful
when trying to diagnose problems with applications that use the Java
Native Interface (JNI). Sometimes there are bugs in the native code
that cause the Java VM to crash or behave incorrectly. Add the -Xcheck:jni option to the command line when starting the
application. For example:
$ java -Xcheck:jni MyApplication |
The -Xcheck:jni tells the Java VM to do additional
validation on the arguments passed to JNI functions. This option may
not find all invalid arguments or diagnose logic bugs in the application
code; however, it can help diagnose these types of problems.
When an invalid argument is detected, the Java
VM prints a message to the application console (standard output),
prints the stack trace of the offending thread, and aborts the Java
VM. The following example shows where a NULL is incorrectly passed
to a JNI function that does not allow NULL:
FATAL ERROR in native method: Null object passed to JNI
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:343)
- locked <0x450b9f70> (a java.net.PlainSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:439)
at java.net.ServerSocket.accept(ServerSocket.java:410)
at org.apache.tomcat.service.PoolTcpEndpoint.acceptSocket(PoolTcpEndpoint.java:286)
at org.apache.tomcat.service.TcpWorkerThread.runIt(PoolTcpEndpoint.java:402)
at org.apache.tomcat.util.ThreadPool$ControlRunnable.run(ThreadPool.java:498)
at java.lang.Thread.run(Thread.java:536) |
The following example shows output that is displayed
when something other than a jfieldID is provided to a JNI function
that expects a jfieldID:
FATAL ERROR in native method: Instance field not found in JNI get/set field operations
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359)
-locked <0xf082f290> (a java.net.PlainSocketImpl)
at java.net.ServerSocket.bind(ServerSocket.java:318)
at java.net.ServerSocket.<init>(ServerSocket.java:185)
at jvm003a.<init>(jvm003.java:190)
at jvm003a.<init>(jvm003.java:151)
at jvm003.run(jvm003.java:51)
at jvm003.main(jvm003.java:30) |
The types of problems that -Xcheck:jni can help diagnose are:
The JNI environment for the wrong thread is used
An invalid JNI reference is used
A reference to a nonarray type is provided to a function
that requires an array type
A nonstatic field ID is provided to a function that
expects a static field ID
A JNI call is made with an exception pending
In general, all errors detected by -Xcheck:jni are fatal; the error is printed and the Java VM is aborted. One
exception to this is a nonfatal warning that is printed when a JNI
call is made within a JNI critical region. This is the warning that
is displayed when this happens:
Warning: Calling other JNI functions in the scope of
Get/ReleasePrimitiveArrayCritical or Get/ReleaseStringCritical |
A JNI critical region arises when native code
uses the JNI GetPrimitiveArrayCritical() or GetStringCritical() functions to obtain a reference to
an array or string in the Java heap. The reference is held until the
native code calls the corresponding release function. The time between
the get and release is called a JNI critical section, and during that
time the Java VM cannot reach a state that allows garbage collection
to occur. The general recommendation is that other JNI functions should
not be used when in a JNI critical section, and in particular any
JNI function that blocks could potentially cause a deadlock. The warning
printed by -Xcheck:jni is an indication of a potential
issue; it does not always indicate an application bug.