Debugging the JNI
If you think you have a JNI problem, there are checks you can run to help you diagnose the JNI transitions.
- The program crashes during execution of a native method (most common).
- The program crashes some time after returning from the native method, often during GC (not so common).
- Bad JNI code causes deadlocks shortly after returning from a native method (occasional).
If you think that you have a problem with the interaction between user-written native code and the JVM (that is, a JNI problem), you can run checks that help you diagnose the JNI transitions. To run these checks, specify the -Xcheck:jni option when you start the JVM.
- Whether the call and the call that initialized JNI are on the same thread.
- Whether the object parameters are valid objects.
- Whether local or global references refer to valid objects.
- Whether the type of a field matches the
Get<Type>Field
orSet<Type>Field
call. - Whether static and nonstatic field IDs are valid.
- Whether strings are valid and non-null.
- Whether array elements are non-null.
- The types on array elements.
Output from -Xcheck:jni is displayed on the standard error stream, and looks like:
JVMJNCK059W: JNI warning in FindClass: argument #2 is a malformed identifier ("invalid.name")
JVMJNCK090W: Warning detected in com/ibm/examples/JNIExample.nativeMethod() [Ljava/lang/String];
- The error level (error, warning, or advice).
- The JNI API in which the error was detected.
- An explanation of the problem.
You can specify additional suboptions by using -Xcheck:jni:<suboption>[,<...>]. Useful suboptions are:
- all
- Check application and system classes.
- verbose
- Trace certain JNI functions and activities.
- trace
- Trace all JNI functions.
- nobounds
- Do not perform bounds checking on strings and arrays.
- nonfatal
- Do not exit when errors are detected.
- nowarn
- Do not display warnings.
- noadvice
- Do not display advice.
- novalist
- Do not check for va_list reuse (see the note at the end of this section).
- pedantic
- Perform more thorough, but slower checks.
- valist
- Check for va_list reuse (see the note at the end of the section).
- help
- Print help information.
The -Xcheck:jni option might reduce performance because it is thorough when it validates the supplied parameters.
On some platforms, reusing a va_list in a second JNI call (for example, when calling CallStaticVoidMethod() twice with the same arguments) causes the va_list to be corrupted and the second call to fail. To ensure that the va_list is not corrupted, use the standard C macro va_copy() in the first call. By default, -Xcheck:jni ensures that va_lists are not being reused. Use the novalist suboption to disable this check only if your platform allows reusing va_list without va_copy. z/OS® platforms allow va_list reuse, and by default -Xcheck:jni:novalist is used. To enable va_list reuse checking, use the -Xcheck:jni:valist option.