During some manual digging through the libhdfs code, we found several places where we are not handling exceptions properly.
Specifically, there seem to be some violation of the following snippet from the JNI Oracle docs (https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#exceptions_and_error_codes):
Exceptions and Error Codes
Certain JNI functions use the Java exception mechanism to report error conditions. In most cases, JNI functions report error conditions by returning an error code and throwing a Java exception. The error code is usually a special return value (such as NULL) that is outside of the range of normal return values. Therefore, the programmer can quickly check the return value of the last JNI call to determine if an error has occurred, and call a function, ExceptionOccurred(), to obtain the exception object that contains a more detailed description of the error condition.
There are two cases where the programmer needs to check for exceptions without being able to first check an error code:
 The JNI functions that invoke a Java method return the result of the Java method. The programmer must call ExceptionOccurred() to check for possible exceptions that occurred during the execution of the Java method.
 Some of the JNI array access functions do not return an error code, but may throw an ArrayIndexOutOfBoundsException or ArrayStoreException.
In all other cases, a non-error return value guarantees that no exceptions have been thrown.
Here is a running list of issues:
- classNameOfObject in jni_helper.c calls CallObjectMethod but does not check if an exception has occurred, it only checks if the result of the method (in this case Class#getName(String)) returns NULL
- Exception handling in get_current_thread_id (both posix/thread_local_storage.c and windows/thread_local_storage.c) seems to have several issues; lots of JNI methods are called without checking for exceptions
- Most of the calls to GetObjectArrayElement and GetByteArrayRegion in hdfs.c do not check for exceptions properly
- e.g. for GetObjectArrayElement they only check if the result of the operation is NULL, but they should call ExceptionOccurred to look for pending exceptions as well