HDFS-3579. libhdfs: fix exception handling. (Colin Patrick McCabe via atm)
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1370016 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2a178a8d0b
commit
7f92566e21
|
@ -403,6 +403,8 @@ Release 2.0.1-alpha - UNRELEASED
|
||||||
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)
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,195 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "exception.h"
|
||||||
|
#include "hdfs.h"
|
||||||
|
#include "jni_helper.h"
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define EXCEPTION_INFO_LEN (sizeof(gExceptionInfo)/sizeof(gExceptionInfo[0]))
|
||||||
|
|
||||||
|
struct ExceptionInfo {
|
||||||
|
const char * const name;
|
||||||
|
int noPrintFlag;
|
||||||
|
int excErrno;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct ExceptionInfo gExceptionInfo[] = {
|
||||||
|
{
|
||||||
|
.name = "java/io/FileNotFoundException",
|
||||||
|
.noPrintFlag = NOPRINT_EXC_FILE_NOT_FOUND,
|
||||||
|
.excErrno = ENOENT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "org/apache/hadoop/security/AccessControlException",
|
||||||
|
.noPrintFlag = NOPRINT_EXC_ACCESS_CONTROL,
|
||||||
|
.excErrno = EACCES,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "org/apache/hadoop/fs/UnresolvedLinkException",
|
||||||
|
.noPrintFlag = NOPRINT_EXC_UNRESOLVED_LINK,
|
||||||
|
.excErrno = ENOLINK,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "org/apache/hadoop/fs/ParentNotDirectoryException",
|
||||||
|
.noPrintFlag = NOPRINT_EXC_PARENT_NOT_DIRECTORY,
|
||||||
|
.excErrno = ENOTDIR,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "java/lang/IllegalArgumentException",
|
||||||
|
.noPrintFlag = NOPRINT_EXC_ILLEGAL_ARGUMENT,
|
||||||
|
.excErrno = EINVAL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "java/lang/OutOfMemoryError",
|
||||||
|
.noPrintFlag = 0,
|
||||||
|
.excErrno = ENOMEM,
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
int printExceptionAndFreeV(JNIEnv *env, jthrowable exc, int noPrintFlags,
|
||||||
|
const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
int i, noPrint, excErrno;
|
||||||
|
char *className = NULL;
|
||||||
|
jstring jStr = NULL;
|
||||||
|
jvalue jVal;
|
||||||
|
jthrowable jthr;
|
||||||
|
|
||||||
|
jthr = classNameOfObject(exc, env, &className);
|
||||||
|
if (jthr) {
|
||||||
|
fprintf(stderr, "PrintExceptionAndFree: error determining class name "
|
||||||
|
"of exception.\n");
|
||||||
|
className = strdup("(unknown)");
|
||||||
|
destroyLocalReference(env, jthr);
|
||||||
|
}
|
||||||
|
for (i = 0; i < EXCEPTION_INFO_LEN; i++) {
|
||||||
|
if (!strcmp(gExceptionInfo[i].name, className)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i < EXCEPTION_INFO_LEN) {
|
||||||
|
noPrint = (gExceptionInfo[i].noPrintFlag & noPrintFlags);
|
||||||
|
excErrno = gExceptionInfo[i].excErrno;
|
||||||
|
} else {
|
||||||
|
noPrint = 0;
|
||||||
|
excErrno = EINTERNAL;
|
||||||
|
}
|
||||||
|
if (!noPrint) {
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
fprintf(stderr, " error:\n");
|
||||||
|
|
||||||
|
// We don't want to use ExceptionDescribe here, because that requires a
|
||||||
|
// pending exception. Instead, use ExceptionUtils.
|
||||||
|
jthr = invokeMethod(env, &jVal, STATIC, NULL,
|
||||||
|
"org/apache/commons/lang/exception/ExceptionUtils",
|
||||||
|
"getStackTrace", "(Ljava/lang/Throwable;)Ljava/lang/String;", exc);
|
||||||
|
if (jthr) {
|
||||||
|
fprintf(stderr, "(unable to get stack trace for %s exception: "
|
||||||
|
"ExceptionUtils::getStackTrace error.)\n", className);
|
||||||
|
destroyLocalReference(env, jthr);
|
||||||
|
} else {
|
||||||
|
jStr = jVal.l;
|
||||||
|
const char *stackTrace = (*env)->GetStringUTFChars(env, jStr, NULL);
|
||||||
|
if (!stackTrace) {
|
||||||
|
fprintf(stderr, "(unable to get stack trace for %s exception: "
|
||||||
|
"GetStringUTFChars error.)\n", className);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s", stackTrace);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, jStr, stackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
destroyLocalReference(env, jStr);
|
||||||
|
destroyLocalReference(env, exc);
|
||||||
|
free(className);
|
||||||
|
return excErrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
int printExceptionAndFree(JNIEnv *env, jthrowable exc, int noPrintFlags,
|
||||||
|
const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
ret = printExceptionAndFreeV(env, exc, noPrintFlags, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int printPendingExceptionAndFree(JNIEnv *env, int noPrintFlags,
|
||||||
|
const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int ret;
|
||||||
|
jthrowable exc;
|
||||||
|
|
||||||
|
exc = (*env)->ExceptionOccurred(env);
|
||||||
|
if (!exc) {
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
fprintf(stderr, " error: (no exception)");
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
(*env)->ExceptionClear(env);
|
||||||
|
va_start(ap, fmt);
|
||||||
|
ret = printExceptionAndFreeV(env, exc, noPrintFlags, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
jthrowable getPendingExceptionAndClear(JNIEnv *env)
|
||||||
|
{
|
||||||
|
jthrowable jthr = (*env)->ExceptionOccurred(env);
|
||||||
|
if (!jthr)
|
||||||
|
return NULL;
|
||||||
|
(*env)->ExceptionClear(env);
|
||||||
|
return jthr;
|
||||||
|
}
|
||||||
|
|
||||||
|
jthrowable newRuntimeError(JNIEnv *env, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char buf[512];
|
||||||
|
jobject out, exc;
|
||||||
|
jstring jstr;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
jstr = (*env)->NewStringUTF(env, buf);
|
||||||
|
if (!jstr) {
|
||||||
|
// We got an out of memory exception rather than a RuntimeException.
|
||||||
|
// Too bad...
|
||||||
|
return getPendingExceptionAndClear(env);
|
||||||
|
}
|
||||||
|
exc = constructNewObjectOfClass(env, &out, "RuntimeException",
|
||||||
|
"(java/lang/String;)V", jstr);
|
||||||
|
(*env)->DeleteLocalRef(env, jstr);
|
||||||
|
// Again, we'll either get an out of memory exception or the
|
||||||
|
// RuntimeException we wanted.
|
||||||
|
return (exc) ? exc : out;
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBHDFS_EXCEPTION_H
|
||||||
|
#define LIBHDFS_EXCEPTION_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception handling routines for libhdfs.
|
||||||
|
*
|
||||||
|
* The convention we follow here is to clear pending exceptions as soon as they
|
||||||
|
* are raised. Never assume that the caller of your function will clean up
|
||||||
|
* after you-- do it yourself. Unhandled exceptions can lead to memory leaks
|
||||||
|
* and other undefined behavior.
|
||||||
|
*
|
||||||
|
* If you encounter an exception, return a local reference to it. The caller is
|
||||||
|
* responsible for freeing the local reference, by calling a function like
|
||||||
|
* PrintExceptionAndFree. (You can also free exceptions directly by calling
|
||||||
|
* DeleteLocalRef. However, that would not produce an error message, so it's
|
||||||
|
* usually not what you want.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <search.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception noprint flags
|
||||||
|
*
|
||||||
|
* Theses flags determine which exceptions should NOT be printed to stderr by
|
||||||
|
* the exception printing routines. For example, if you expect to see
|
||||||
|
* FileNotFound, you might use NOPRINT_EXC_FILE_NOT_FOUND, to avoid filling the
|
||||||
|
* logs with messages about routine events.
|
||||||
|
*
|
||||||
|
* On the other hand, if you don't expect any failures, you might pass
|
||||||
|
* PRINT_EXC_ALL.
|
||||||
|
*
|
||||||
|
* You can OR these flags together to avoid printing multiple classes of
|
||||||
|
* exceptions.
|
||||||
|
*/
|
||||||
|
#define PRINT_EXC_ALL 0x00
|
||||||
|
#define NOPRINT_EXC_FILE_NOT_FOUND 0x01
|
||||||
|
#define NOPRINT_EXC_ACCESS_CONTROL 0x02
|
||||||
|
#define NOPRINT_EXC_UNRESOLVED_LINK 0x04
|
||||||
|
#define NOPRINT_EXC_PARENT_NOT_DIRECTORY 0x08
|
||||||
|
#define NOPRINT_EXC_ILLEGAL_ARGUMENT 0x10
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print out information about an exception and free it.
|
||||||
|
*
|
||||||
|
* @param env The JNI environment
|
||||||
|
* @param exc The exception to print and free
|
||||||
|
* @param noPrintFlags Flags which determine which exceptions we should NOT
|
||||||
|
* print.
|
||||||
|
* @param fmt Printf-style format list
|
||||||
|
* @param ap Printf-style varargs
|
||||||
|
*
|
||||||
|
* @return The POSIX error number associated with the exception
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
int printExceptionAndFreeV(JNIEnv *env, jthrowable exc, int noPrintFlags,
|
||||||
|
const char *fmt, va_list ap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print out information about an exception and free it.
|
||||||
|
*
|
||||||
|
* @param env The JNI environment
|
||||||
|
* @param exc The exception to print and free
|
||||||
|
* @param noPrintFlags Flags which determine which exceptions we should NOT
|
||||||
|
* print.
|
||||||
|
* @param fmt Printf-style format list
|
||||||
|
* @param ... Printf-style varargs
|
||||||
|
*
|
||||||
|
* @return The POSIX error number associated with the exception
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
int printExceptionAndFree(JNIEnv *env, jthrowable exc, int noPrintFlags,
|
||||||
|
const char *fmt, ...) __attribute__((format(printf, 4, 5)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print out information about the pending exception and free it.
|
||||||
|
*
|
||||||
|
* @param env The JNI environment
|
||||||
|
* @param noPrintFlags Flags which determine which exceptions we should NOT
|
||||||
|
* print.
|
||||||
|
* @param fmt Printf-style format list
|
||||||
|
* @param ... Printf-style varargs
|
||||||
|
*
|
||||||
|
* @return The POSIX error number associated with the exception
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
int printPendingExceptionAndFree(JNIEnv *env, int noPrintFlags,
|
||||||
|
const char *fmt, ...) __attribute__((format(printf, 3, 4)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a local reference to the pending exception and clear it.
|
||||||
|
*
|
||||||
|
* Once it is cleared, the exception will no longer be pending. The caller will
|
||||||
|
* have to decide what to do with the exception object.
|
||||||
|
*
|
||||||
|
* @param env The JNI environment
|
||||||
|
*
|
||||||
|
* @return The exception, or NULL if there was no exception
|
||||||
|
*/
|
||||||
|
jthrowable getPendingExceptionAndClear(JNIEnv *env);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new runtime error.
|
||||||
|
*
|
||||||
|
* This creates (but does not throw) a new RuntimeError.
|
||||||
|
*
|
||||||
|
* @param env The JNI environment
|
||||||
|
* @param fmt Printf-style format list
|
||||||
|
* @param ... Printf-style varargs
|
||||||
|
*
|
||||||
|
* @return A local reference to a RuntimeError
|
||||||
|
*/
|
||||||
|
jthrowable newRuntimeError(JNIEnv *env, const char *fmt, ...)
|
||||||
|
__attribute__((format(printf, 2, 3)));
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -253,6 +253,8 @@ extern "C" {
|
||||||
* 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);
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue