HDFS-3579. libhdfs: fix exception handling. Contributed by Colin Patrick McCabe.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1370015 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Aaron Myers 2012-08-06 21:02:30 +00:00
parent 117145f1ad
commit f7b37c009b
7 changed files with 1378 additions and 1349 deletions

View File

@ -557,6 +557,8 @@ Branch-2 ( Unreleased changes )
HDFS-3719. Re-enable append-related tests in TestFileConcurrentReader. HDFS-3719. Re-enable append-related tests in TestFileConcurrentReader.
(Andrew Wang via atm) (Andrew Wang via atm)
HDFS-3579. libhdfs: fix exception handling. (Colin Patrick McCabe via atm)
BREAKDOWN OF HDFS-3042 SUBTASKS BREAKDOWN OF HDFS-3042 SUBTASKS
HDFS-2185. HDFS portion of ZK-based FailoverController (todd) HDFS-2185. HDFS portion of ZK-based FailoverController (todd)

View File

@ -95,6 +95,7 @@ set(_FUSE_DFS_VERSION 0.1.0)
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_BINARY_DIR}/config.h) CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_BINARY_DIR}/config.h)
add_dual_library(hdfs add_dual_library(hdfs
main/native/libhdfs/exception.c
main/native/libhdfs/hdfs.c main/native/libhdfs/hdfs.c
main/native/libhdfs/jni_helper.c main/native/libhdfs/jni_helper.c
) )

File diff suppressed because it is too large Load Diff

View File

@ -252,7 +252,9 @@ extern "C" {
* hdfsDisconnect - Disconnect from the hdfs file system. * hdfsDisconnect - Disconnect from the hdfs file system.
* Disconnect from hdfs. * Disconnect from hdfs.
* @param fs The configured filesystem handle. * @param fs The configured filesystem handle.
* @return Returns 0 on success, -1 on error. * @return Returns 0 on success, -1 on error.
* Even if there is an error, the resources associated with the
* hdfsFS will be freed.
*/ */
int hdfsDisconnect(hdfsFS fs); int hdfsDisconnect(hdfsFS fs);
@ -280,6 +282,10 @@ extern "C" {
* @param fs The configured filesystem handle. * @param fs The configured filesystem handle.
* @param file The file handle. * @param file The file handle.
* @return Returns 0 on success, -1 on error. * @return Returns 0 on success, -1 on error.
* On error, errno will be set appropriately.
* If the hdfs file was valid, the memory associated with it will
* be freed at the end of this call, even if there was an I/O
* error.
*/ */
int hdfsCloseFile(hdfsFS fs, hdfsFile file); int hdfsCloseFile(hdfsFS fs, hdfsFile file);
@ -336,8 +342,7 @@ extern "C" {
* @param position Position from which to read * @param position Position from which to read
* @param buffer The buffer to copy read bytes into. * @param buffer The buffer to copy read bytes into.
* @param length The length of the buffer. * @param length The length of the buffer.
* @return Returns the number of bytes actually read, possibly less than * @return See hdfsRead
* than length;-1 on error.
*/ */
tSize hdfsPread(hdfsFS fs, hdfsFile file, tOffset position, tSize hdfsPread(hdfsFS fs, hdfsFile file, tOffset position,
void* buffer, tSize length); void* buffer, tSize length);

View File

@ -17,6 +17,7 @@
*/ */
#include "config.h" #include "config.h"
#include "exception.h"
#include "jni_helper.h" #include "jni_helper.h"
#include <stdio.h> #include <stdio.h>
@ -85,16 +86,57 @@ static void hdfsThreadDestructor(void *v)
free(tls); free(tls);
} }
void destroyLocalReference(JNIEnv *env, jobject jObject)
static int validateMethodType(MethType methType)
{ {
if (methType != STATIC && methType != INSTANCE) { if (jObject)
fprintf(stderr, "Unimplemented method type\n"); (*env)->DeleteLocalRef(env, jObject);
return 0;
}
return 1;
} }
static jthrowable validateMethodType(JNIEnv *env, MethType methType)
{
if (methType != STATIC && methType != INSTANCE) {
return newRuntimeError(env, "validateMethodType(methType=%d): "
"illegal method type.\n", methType);
}
return NULL;
}
jthrowable newJavaStr(JNIEnv *env, const char *str, jstring *out)
{
jstring jstr;
if (!str) {
/* Can't pass NULL to NewStringUTF: the result would be
* implementation-defined. */
*out = NULL;
return NULL;
}
jstr = (*env)->NewStringUTF(env, str);
if (!jstr) {
/* If NewStringUTF returns NULL, an exception has been thrown,
* which we need to handle. Probaly an OOM. */
return getPendingExceptionAndClear(env);
}
*out = jstr;
return NULL;
}
jthrowable newCStr(JNIEnv *env, jstring jstr, char **out)
{
const char *tmp;
if (!jstr) {
*out = NULL;
return NULL;
}
tmp = (*env)->GetStringUTFChars(env, jstr, NULL);
if (!tmp) {
return getPendingExceptionAndClear(env);
}
*out = strdup(tmp);
(*env)->ReleaseStringUTFChars(env, jstr, tmp);
return NULL;
}
static int hashTableInit(void) static int hashTableInit(void)
{ {
@ -156,7 +198,7 @@ static void* searchEntryFromTable(const char *key)
int invokeMethod(JNIEnv *env, RetVal *retval, Exc *exc, MethType methType, jthrowable invokeMethod(JNIEnv *env, jvalue *retval, MethType methType,
jobject instObj, const char *className, jobject instObj, const char *className,
const char *methName, const char *methSignature, ...) const char *methName, const char *methSignature, ...)
{ {
@ -167,21 +209,16 @@ int invokeMethod(JNIEnv *env, RetVal *retval, Exc *exc, MethType methType,
const char *str; const char *str;
char returnType; char returnType;
if (! validateMethodType(methType)) { jthr = validateMethodType(env, methType);
return -1; if (jthr)
} return jthr;
cls = globalClassReference(className, env); jthr = globalClassReference(className, env, &cls);
if (cls == NULL) { if (jthr)
return -2; return jthr;
} jthr = methodIdFromClass(className, methName, methSignature,
methType, env, &mid);
mid = methodIdFromClass(className, methName, methSignature, if (jthr)
methType, env); return jthr;
if (mid == NULL) {
(*env)->ExceptionDescribe(env);
return -3;
}
str = methSignature; str = methSignature;
while (*str != ')') str++; while (*str != ')') str++;
str++; str++;
@ -248,43 +285,14 @@ int invokeMethod(JNIEnv *env, RetVal *retval, Exc *exc, MethType methType,
va_end(args); va_end(args);
jthr = (*env)->ExceptionOccurred(env); jthr = (*env)->ExceptionOccurred(env);
if (jthr != NULL) { if (jthr) {
if (exc != NULL) (*env)->ExceptionClear(env);
*exc = jthr; return jthr;
else
(*env)->ExceptionDescribe(env);
return -1;
} }
return 0; return NULL;
} }
jarray constructNewArrayString(JNIEnv *env, Exc *exc, const char **elements, int size) { jthrowable constructNewObjectOfClass(JNIEnv *env, jobject *out, const char *className,
const char *className = "java/lang/String";
jobjectArray result;
int i;
jclass arrCls = (*env)->FindClass(env, className);
if (arrCls == NULL) {
fprintf(stderr, "could not find class %s\n",className);
return NULL; /* exception thrown */
}
result = (*env)->NewObjectArray(env, size, arrCls,
NULL);
if (result == NULL) {
fprintf(stderr, "ERROR: could not construct new array\n");
return NULL; /* out of memory error thrown */
}
for (i = 0; i < size; i++) {
jstring jelem = (*env)->NewStringUTF(env,elements[i]);
if (jelem == NULL) {
fprintf(stderr, "ERROR: jelem == NULL\n");
}
(*env)->SetObjectArrayElement(env, result, i, jelem);
(*env)->DeleteLocalRef(env, jelem);
}
return result;
}
jobject constructNewObjectOfClass(JNIEnv *env, Exc *exc, const char *className,
const char *ctorSignature, ...) const char *ctorSignature, ...)
{ {
va_list args; va_list args;
@ -293,50 +301,37 @@ jobject constructNewObjectOfClass(JNIEnv *env, Exc *exc, const char *className,
jobject jobj; jobject jobj;
jthrowable jthr; jthrowable jthr;
cls = globalClassReference(className, env); jthr = globalClassReference(className, env, &cls);
if (cls == NULL) { if (jthr)
(*env)->ExceptionDescribe(env); return jthr;
return NULL; jthr = methodIdFromClass(className, "<init>", ctorSignature,
} INSTANCE, env, &mid);
if (jthr)
mid = methodIdFromClass(className, "<init>", ctorSignature, return jthr;
INSTANCE, env);
if (mid == NULL) {
(*env)->ExceptionDescribe(env);
return NULL;
}
va_start(args, ctorSignature); va_start(args, ctorSignature);
jobj = (*env)->NewObjectV(env, cls, mid, args); jobj = (*env)->NewObjectV(env, cls, mid, args);
va_end(args); va_end(args);
jthr = (*env)->ExceptionOccurred(env); if (!jobj)
if (jthr != NULL) { return getPendingExceptionAndClear(env);
if (exc != NULL) *out = jobj;
*exc = jthr; return NULL;
else
(*env)->ExceptionDescribe(env);
}
return jobj;
} }
jthrowable methodIdFromClass(const char *className, const char *methName,
jmethodID methodIdFromClass(const char *className, const char *methName,
const char *methSignature, MethType methType, const char *methSignature, MethType methType,
JNIEnv *env) JNIEnv *env, jmethodID *out)
{ {
jclass cls = globalClassReference(className, env); jclass cls;
if (cls == NULL) { jthrowable jthr;
fprintf(stderr, "could not find class %s\n", className);
return NULL;
}
jthr = globalClassReference(className, env, &cls);
if (jthr)
return jthr;
jmethodID mid = 0; jmethodID mid = 0;
if (!validateMethodType(methType)) { jthr = validateMethodType(env, methType);
fprintf(stderr, "invalid method type\n"); if (jthr)
return NULL; return jthr;
}
if (methType == STATIC) { if (methType == STATIC) {
mid = (*env)->GetStaticMethodID(env, cls, methName, methSignature); mid = (*env)->GetStaticMethodID(env, cls, methName, methSignature);
} }
@ -344,72 +339,88 @@ jmethodID methodIdFromClass(const char *className, const char *methName,
mid = (*env)->GetMethodID(env, cls, methName, methSignature); mid = (*env)->GetMethodID(env, cls, methName, methSignature);
} }
if (mid == NULL) { if (mid == NULL) {
fprintf(stderr, "could not find method %s from class %s with signature %s\n",methName, className, methSignature); fprintf(stderr, "could not find method %s from class %s with "
"signature %s\n", methName, className, methSignature);
return getPendingExceptionAndClear(env);
} }
return mid; *out = mid;
return NULL;
} }
jthrowable globalClassReference(const char *className, JNIEnv *env, jclass *out)
jclass globalClassReference(const char *className, JNIEnv *env)
{ {
jclass clsLocalRef; jclass clsLocalRef;
jclass cls = searchEntryFromTable(className); jclass cls = searchEntryFromTable(className);
if (cls) { if (cls) {
return cls; *out = cls;
return NULL;
} }
clsLocalRef = (*env)->FindClass(env,className); clsLocalRef = (*env)->FindClass(env,className);
if (clsLocalRef == NULL) { if (clsLocalRef == NULL) {
(*env)->ExceptionDescribe(env); return getPendingExceptionAndClear(env);
return NULL;
} }
cls = (*env)->NewGlobalRef(env, clsLocalRef); cls = (*env)->NewGlobalRef(env, clsLocalRef);
if (cls == NULL) { if (cls == NULL) {
(*env)->ExceptionDescribe(env); (*env)->DeleteLocalRef(env, clsLocalRef);
return NULL; return getPendingExceptionAndClear(env);
} }
(*env)->DeleteLocalRef(env, clsLocalRef); (*env)->DeleteLocalRef(env, clsLocalRef);
insertEntryIntoTable(className, cls); insertEntryIntoTable(className, cls);
return cls; *out = cls;
return NULL;
} }
jthrowable classNameOfObject(jobject jobj, JNIEnv *env, char **name)
char *classNameOfObject(jobject jobj, JNIEnv *env) { {
jclass cls, clsClass; jthrowable jthr;
jclass cls, clsClass = NULL;
jmethodID mid; jmethodID mid;
jstring str; jstring str = NULL;
const char *cstr; const char *cstr = NULL;
char *newstr; char *newstr;
cls = (*env)->GetObjectClass(env, jobj); cls = (*env)->GetObjectClass(env, jobj);
if (cls == NULL) { if (cls == NULL) {
(*env)->ExceptionDescribe(env); jthr = getPendingExceptionAndClear(env);
return NULL; goto done;
} }
clsClass = (*env)->FindClass(env, "java/lang/Class"); clsClass = (*env)->FindClass(env, "java/lang/Class");
if (clsClass == NULL) { if (clsClass == NULL) {
(*env)->ExceptionDescribe(env); jthr = getPendingExceptionAndClear(env);
return NULL; goto done;
} }
mid = (*env)->GetMethodID(env, clsClass, "getName", "()Ljava/lang/String;"); mid = (*env)->GetMethodID(env, clsClass, "getName", "()Ljava/lang/String;");
if (mid == NULL) { if (mid == NULL) {
(*env)->ExceptionDescribe(env); jthr = getPendingExceptionAndClear(env);
return NULL; goto done;
} }
str = (*env)->CallObjectMethod(env, cls, mid); str = (*env)->CallObjectMethod(env, cls, mid);
if (str == NULL) { if (str == NULL) {
(*env)->ExceptionDescribe(env); jthr = getPendingExceptionAndClear(env);
return NULL; goto done;
} }
cstr = (*env)->GetStringUTFChars(env, str, NULL); cstr = (*env)->GetStringUTFChars(env, str, NULL);
newstr = strdup(cstr); if (!cstr) {
(*env)->ReleaseStringUTFChars(env, str, cstr); jthr = getPendingExceptionAndClear(env);
if (newstr == NULL) { goto done;
perror("classNameOfObject: strdup");
return NULL;
} }
return newstr; newstr = strdup(cstr);
if (newstr == NULL) {
jthr = newRuntimeError(env, "classNameOfObject: out of memory");
goto done;
}
*name = newstr;
jthr = NULL;
done:
destroyLocalReference(env, cls);
destroyLocalReference(env, clsClass);
if (str) {
if (cstr)
(*env)->ReleaseStringUTFChars(env, str, cstr);
(*env)->DeleteLocalRef(env, str);
}
return jthr;
} }
@ -429,6 +440,7 @@ static JNIEnv* getGlobalJNIEnv(void)
JNIEnv *env; JNIEnv *env;
jint rv = 0; jint rv = 0;
jint noVMs = 0; jint noVMs = 0;
jthrowable jthr;
rv = JNI_GetCreatedJavaVMs(&(vmBuf[0]), vmBufLength, &noVMs); rv = JNI_GetCreatedJavaVMs(&(vmBuf[0]), vmBufLength, &noVMs);
if (rv != 0) { if (rv != 0) {
@ -501,10 +513,11 @@ static JNIEnv* getGlobalJNIEnv(void)
"with error: %d\n", rv); "with error: %d\n", rv);
return NULL; return NULL;
} }
if (invokeMethod(env, NULL, NULL, STATIC, NULL, jthr = invokeMethod(env, NULL, STATIC, NULL,
"org/apache/hadoop/fs/FileSystem", "org/apache/hadoop/fs/FileSystem",
"loadFileSystems", "()V") != 0) { "loadFileSystems", "()V");
(*env)->ExceptionDescribe(env); if (jthr) {
printExceptionAndFree(env, jthr, PRINT_EXC_ALL, "loadFileSystems");
} }
} }
else { else {

View File

@ -37,14 +37,35 @@ typedef enum {
INSTANCE INSTANCE
} MethType; } MethType;
/**
/** Used for returning an appropriate return value after invoking * Create a new malloc'ed C string from a Java string.
* a method *
* @param env The JNI environment
* @param jstr The Java string
* @param out (out param) the malloc'ed C string
*
* @return NULL on success; the exception otherwise
*/ */
typedef jvalue RetVal; jthrowable newCStr(JNIEnv *env, jstring jstr, char **out);
/** Used for returning the exception after invoking a method */ /**
typedef jthrowable Exc; * Create a new Java string from a C string.
*
* @param env The JNI environment
* @param str The C string
* @param out (out param) the java string
*
* @return NULL on success; the exception otherwise
*/
jthrowable newJavaStr(JNIEnv *env, const char *str, jstring *out);
/**
* Helper function to destroy a local reference of java.lang.Object
* @param env: The JNIEnv pointer.
* @param jFile: The local reference of java.lang.Object object
* @return None.
*/
void destroyLocalReference(JNIEnv *env, jobject jObject);
/** invokeMethod: Invoke a Static or Instance method. /** invokeMethod: Invoke a Static or Instance method.
* className: Name of the class where the method can be found * className: Name of the class where the method can be found
@ -63,33 +84,27 @@ typedef jthrowable Exc;
* RETURNS: -1 on error and 0 on success. If -1 is returned, exc will have * RETURNS: -1 on error and 0 on success. If -1 is returned, exc will have
a valid exception reference, and the result stored at retval is undefined. a valid exception reference, and the result stored at retval is undefined.
*/ */
int invokeMethod(JNIEnv *env, RetVal *retval, Exc *exc, MethType methType, jthrowable invokeMethod(JNIEnv *env, jvalue *retval, MethType methType,
jobject instObj, const char *className, const char *methName, jobject instObj, const char *className, const char *methName,
const char *methSignature, ...); const char *methSignature, ...);
/** constructNewObjectOfClass: Invoke a constructor. jthrowable constructNewObjectOfClass(JNIEnv *env, jobject *out, const char *className,
* className: Name of the class
* ctorSignature: the signature of the constructor "(arg-types)V"
* env: The JNIEnv pointer
* exc: If the ctor throws any exception, this will contain the reference
* Arguments to the ctor must be passed after ctorSignature
*/
jobject constructNewObjectOfClass(JNIEnv *env, Exc *exc, const char *className,
const char *ctorSignature, ...); const char *ctorSignature, ...);
jmethodID methodIdFromClass(const char *className, const char *methName, jthrowable methodIdFromClass(const char *className, const char *methName,
const char *methSignature, MethType methType, const char *methSignature, MethType methType,
JNIEnv *env); JNIEnv *env, jmethodID *out);
jclass globalClassReference(const char *className, JNIEnv *env); jthrowable globalClassReference(const char *className, JNIEnv *env, jclass *out);
/** classNameOfObject: Get an object's class name. /** classNameOfObject: Get an object's class name.
* @param jobj: The object. * @param jobj: The object.
* @param env: The JNIEnv pointer. * @param env: The JNIEnv pointer.
* @return Returns a pointer to a string containing the class name. This string * @param name: (out param) On success, will contain a string containing the
* must be freed by the caller. * class name. This string must be freed by the caller.
* @return NULL on success, or the exception
*/ */
char *classNameOfObject(jobject jobj, JNIEnv *env); jthrowable classNameOfObject(jobject jobj, JNIEnv *env, char **name);
/** getJNIEnv: A helper function to get the JNIEnv* for the given thread. /** getJNIEnv: A helper function to get the JNIEnv* for the given thread.
* If no JVM exists, then one will be created. JVM command line arguments * If no JVM exists, then one will be created. JVM command line arguments
@ -99,8 +114,6 @@ char *classNameOfObject(jobject jobj, JNIEnv *env);
* */ * */
JNIEnv* getJNIEnv(void); JNIEnv* getJNIEnv(void);
jarray constructNewArrayString(JNIEnv *env, Exc *exc, const char **elements, int size) ;
#endif /*LIBHDFS_JNI_HELPER_H*/ #endif /*LIBHDFS_JNI_HELPER_H*/
/** /**

View File

@ -16,6 +16,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "exception.h"
#include "jni_helper.h" #include "jni_helper.h"
#include "native_mini_dfs.h" #include "native_mini_dfs.h"
@ -41,6 +42,8 @@ struct NativeMiniDfsCluster* nmdCreate(struct NativeMiniDfsConf *conf)
jobject bld = NULL, bld2 = NULL, cobj = NULL; jobject bld = NULL, bld2 = NULL, cobj = NULL;
jvalue val; jvalue val;
JNIEnv *env = getJNIEnv(); JNIEnv *env = getJNIEnv();
jthrowable jthr;
if (!env) { if (!env) {
fprintf(stderr, "nmdCreate: unable to construct JNIEnv.\n"); fprintf(stderr, "nmdCreate: unable to construct JNIEnv.\n");
goto error; goto error;
@ -50,35 +53,38 @@ struct NativeMiniDfsCluster* nmdCreate(struct NativeMiniDfsConf *conf)
fprintf(stderr, "nmdCreate: OOM"); fprintf(stderr, "nmdCreate: OOM");
goto error; goto error;
} }
cobj = constructNewObjectOfClass(env, NULL, HADOOP_CONF, "()V"); jthr = constructNewObjectOfClass(env, &cobj, HADOOP_CONF, "()V");
if (!cobj) { if (jthr) {
fprintf(stderr, "nmdCreate: unable to construct Configuration\n"); printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"nmdCreate: new Configuration");
goto error_free_cl; goto error_free_cl;
} }
bld = constructNewObjectOfClass(env, NULL, MINIDFS_CLUSTER_BUILDER, jthr = constructNewObjectOfClass(env, &bld, MINIDFS_CLUSTER_BUILDER,
"(L"HADOOP_CONF";)V", cobj); "(L"HADOOP_CONF";)V", cobj);
if (!bld) { if (jthr) {
fprintf(stderr, "nmdCreate: unable to construct " printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"NativeMiniDfsCluster#Builder\n"); "nmdCreate: NativeMiniDfsCluster#Builder#Builder");
goto error_dlr_cobj; goto error_dlr_cobj;
} }
if (invokeMethod(env, &val, NULL, INSTANCE, bld, jthr = invokeMethod(env, &val, INSTANCE, bld, MINIDFS_CLUSTER_BUILDER,
MINIDFS_CLUSTER_BUILDER, "format", "format", "(Z)L" MINIDFS_CLUSTER_BUILDER ";", conf->doFormat);
"(Z)L" MINIDFS_CLUSTER_BUILDER ";", conf->doFormat)) { if (jthr) {
fprintf(stderr, "nmdCreate: failed to call Builder#doFormat\n"); printExceptionAndFree(env, jthr, PRINT_EXC_ALL, "nmdCreate: "
"Builder::format");
goto error_dlr_bld; goto error_dlr_bld;
} }
bld2 = val.l; bld2 = val.l;
if (invokeMethod(env, &val, NULL, INSTANCE, bld, jthr = invokeMethod(env, &val, INSTANCE, bld, MINIDFS_CLUSTER_BUILDER,
MINIDFS_CLUSTER_BUILDER, "build", "build", "()L" MINIDFS_CLUSTER ";");
"()L" MINIDFS_CLUSTER ";")) { if (jthr) {
fprintf(stderr, "nmdCreate: failed to call Builder#build\n"); printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"nmdCreate: Builder#build");
goto error_dlr_bld2; goto error_dlr_bld2;
} }
cl->obj = (*env)->NewGlobalRef(env, val.l); cl->obj = (*env)->NewGlobalRef(env, val.l);
if (!cl->obj) { if (!cl->obj) {
fprintf(stderr, "nmdCreate: failed to create global reference to " printPendingExceptionAndFree(env, PRINT_EXC_ALL,
"MiniDFSCluster\n"); "nmdCreate: NewGlobalRef");
goto error_dlr_val; goto error_dlr_val;
} }
(*env)->DeleteLocalRef(env, val.l); (*env)->DeleteLocalRef(env, val.l);
@ -116,13 +122,17 @@ void nmdFree(struct NativeMiniDfsCluster* cl)
int nmdShutdown(struct NativeMiniDfsCluster* cl) int nmdShutdown(struct NativeMiniDfsCluster* cl)
{ {
JNIEnv *env = getJNIEnv(); JNIEnv *env = getJNIEnv();
jthrowable jthr;
if (!env) { if (!env) {
fprintf(stderr, "nmdShutdown: getJNIEnv failed\n"); fprintf(stderr, "nmdShutdown: getJNIEnv failed\n");
return -EIO; return -EIO;
} }
if (invokeMethod(env, NULL, NULL, INSTANCE, cl->obj, jthr = invokeMethod(env, NULL, INSTANCE, cl->obj,
MINIDFS_CLUSTER, "shutdown", "()V")) { MINIDFS_CLUSTER, "shutdown", "()V");
fprintf(stderr, "nmdShutdown: MiniDFSCluster#shutdown failure\n"); if (jthr) {
printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"nmdShutdown: MiniDFSCluster#shutdown");
return -EIO; return -EIO;
} }
return 0; return 0;
@ -130,15 +140,17 @@ int nmdShutdown(struct NativeMiniDfsCluster* cl)
int nmdWaitClusterUp(struct NativeMiniDfsCluster *cl) int nmdWaitClusterUp(struct NativeMiniDfsCluster *cl)
{ {
jthrowable jthr;
JNIEnv *env = getJNIEnv(); JNIEnv *env = getJNIEnv();
if (!env) { if (!env) {
fprintf(stderr, "nmdWaitClusterUp: getJNIEnv failed\n"); fprintf(stderr, "nmdWaitClusterUp: getJNIEnv failed\n");
return -EIO; return -EIO;
} }
if (invokeMethod(env, NULL, NULL, INSTANCE, cl->obj, jthr = invokeMethod(env, NULL, INSTANCE, cl->obj,
MINIDFS_CLUSTER, "waitClusterUp", "()V")) { MINIDFS_CLUSTER, "waitClusterUp", "()V");
fprintf(stderr, "nmdWaitClusterUp: MiniDFSCluster#waitClusterUp " if (jthr) {
"failure\n"); printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"nmdWaitClusterUp: MiniDFSCluster#waitClusterUp ");
return -EIO; return -EIO;
} }
return 0; return 0;
@ -148,6 +160,7 @@ int nmdGetNameNodePort(struct NativeMiniDfsCluster *cl)
{ {
JNIEnv *env = getJNIEnv(); JNIEnv *env = getJNIEnv();
jvalue jVal; jvalue jVal;
jthrowable jthr;
if (!env) { if (!env) {
fprintf(stderr, "nmdHdfsConnect: getJNIEnv failed\n"); fprintf(stderr, "nmdHdfsConnect: getJNIEnv failed\n");
@ -155,10 +168,11 @@ int nmdGetNameNodePort(struct NativeMiniDfsCluster *cl)
} }
// Note: this will have to be updated when HA nativeMiniDfs clusters are // Note: this will have to be updated when HA nativeMiniDfs clusters are
// supported // supported
if (invokeMethod(env, &jVal, NULL, INSTANCE, cl->obj, jthr = invokeMethod(env, &jVal, INSTANCE, cl->obj,
MINIDFS_CLUSTER, "getNameNodePort", "()I")) { MINIDFS_CLUSTER, "getNameNodePort", "()I");
fprintf(stderr, "nmdHdfsConnect: MiniDFSCluster#getNameNodePort " if (jthr) {
"failure\n"); printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"nmdHdfsConnect: MiniDFSCluster#getNameNodePort");
return -EIO; return -EIO;
} }
return jVal.i; return jVal.i;