Debugging the JNI

If you think you have a JNI problem, there are checks you can run to help you diagnose the JNI transitions.

Errors in JNI code can occur in several ways:
  • 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.

The -Xcheck:jni option activates a set of wrapper functions around the JNI functions. The wrapper functions perform checks on the incoming parameters. These checks include:
  • 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 or Set<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 first line indicates:
  • The error level (error, warning, or advice).
  • The JNI API in which the error was detected.
  • An explanation of the problem.
The last line indicates the native method that was being executed when the error was detected.

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.

Note:

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.