We have several JNI warnings in the JavaFX native JNI libraries. Most are a result of not checking pending exceptions that might be thrown as the result of one JNI call prior to calling certain other calls.
This is an umbrella task. As we find issues, we will file a bug for each area of the code and link it as a blocking issue.
Here are some best practices we should follow. This was initially taken fromJDK-8304290 and fixed up slightly.
Check for exception first and then for return value. For example:
jclass klass = env->FindClass("com/sun/media/jfxmedia/locator/ConnectionHolder");
if (env->ExceptionCheck()) {
env->ExceptionClear();
return error;
}
if (klass == NULL) {
return error;
}
// Do something with klass
alternatively, if this is a JNI native method that is called only from Java we can avoid clearing the exception:
if (env->ExceptionCheck() || klass == NULL) {
return error;
}
// Do something with klass
NOTE: If you need the exception object in native code, e.g., to get values from exception, then use ExceptionOccurred(), otherwise use ExceptionCheck()
Example:
Use this: if (env->ExceptionCheck()) { env->ExceptionClear(); }
Not this: if (env->ExceptionOccurred()) { env->ExceptionClear(); }
The following list of functions were identified as functions which can throw exception(s), based on the JNI spec:
DefineClass
FindClass
AllocObject
NewObject
GetFieldID
GetMethodID
Call<type>Method Routines, Call<type>MethodA Routines, Call<type>MethodV Routines
CallNonvirtual<type>Method Routines, CallNonvirtual<type>MethodA Routines, CallNonvirtual<type>MethodV Routines
GetStaticFieldID
GetStaticMethodID
CallStatic<type>Method Routines, CallStatic<type>MethodA Routines, CallStatic<type>MethodV Routines
NewString
NewStringUTF
GetStringRegion
GetStringUTFRegion
NewObjectArray
New<PrimitiveType>Array Routines
NewWeakGlobalRef
GetObjectArrayElement
SetObjectArrayElement
Get<PrimitiveType>ArrayElements Routines
Get<PrimitiveType>ArrayRegion Routines
Set<PrimitiveType>ArrayRegion Routines
RegisterNatives
MonitorExit
NewDirectByteBuffer
We need to check and clear any pending exceptions after calling any of the above, unless we are in a JNI function called directly from Java code, and we return without making any other JNI calls (other than release, delete, or exception calls).
I presume that an exception check is *not* needed after the following:
GetPrimitiveArrayCritical
Recent docs (e.g., JDK 17 JNI spec) specify that this could throw OOME. Earlier (JDK 8) docs do not mention any exception or errors, and none of the examples, even in the latest docs, show any exception checks. They do document the need to check for null, which we should already be doing, but is worth verifying.
This is an umbrella task. As we find issues, we will file a bug for each area of the code and link it as a blocking issue.
Here are some best practices we should follow. This was initially taken from
Check for exception first and then for return value. For example:
jclass klass = env->FindClass("com/sun/media/jfxmedia/locator/ConnectionHolder");
if (env->ExceptionCheck()) {
env->ExceptionClear();
return error;
}
if (klass == NULL) {
return error;
}
// Do something with klass
alternatively, if this is a JNI native method that is called only from Java we can avoid clearing the exception:
if (env->ExceptionCheck() || klass == NULL) {
return error;
}
// Do something with klass
NOTE: If you need the exception object in native code, e.g., to get values from exception, then use ExceptionOccurred(), otherwise use ExceptionCheck()
Example:
Use this: if (env->ExceptionCheck()) { env->ExceptionClear(); }
Not this: if (env->ExceptionOccurred()) { env->ExceptionClear(); }
The following list of functions were identified as functions which can throw exception(s), based on the JNI spec:
DefineClass
FindClass
AllocObject
NewObject
GetFieldID
GetMethodID
Call<type>Method Routines, Call<type>MethodA Routines, Call<type>MethodV Routines
CallNonvirtual<type>Method Routines, CallNonvirtual<type>MethodA Routines, CallNonvirtual<type>MethodV Routines
GetStaticFieldID
GetStaticMethodID
CallStatic<type>Method Routines, CallStatic<type>MethodA Routines, CallStatic<type>MethodV Routines
NewString
NewStringUTF
GetStringRegion
GetStringUTFRegion
NewObjectArray
New<PrimitiveType>Array Routines
NewWeakGlobalRef
GetObjectArrayElement
SetObjectArrayElement
Get<PrimitiveType>ArrayElements Routines
Get<PrimitiveType>ArrayRegion Routines
Set<PrimitiveType>ArrayRegion Routines
RegisterNatives
MonitorExit
NewDirectByteBuffer
We need to check and clear any pending exceptions after calling any of the above, unless we are in a JNI function called directly from Java code, and we return without making any other JNI calls (other than release, delete, or exception calls).
I presume that an exception check is *not* needed after the following:
GetPrimitiveArrayCritical
Recent docs (e.g., JDK 17 JNI spec) specify that this could throw OOME. Earlier (JDK 8) docs do not mention any exception or errors, and none of the examples, even in the latest docs, show any exception checks. They do document the need to check for null, which we should already be doing, but is worth verifying.
- is blocked by
-
JDK-8309625 Some JNI calls made without checking exceptions in jpegloader
- Open
-
JDK-8309631 Some JNI calls made without checking exceptions in glass
- Open
-
JDK-8304290 Some JNI calls made without checking exceptions in media
- Resolved