123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- /**
- * 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,
- },
-
- };
- void getExceptionInfo(const char *excName, int noPrintFlags,
- int *excErrno, int *shouldPrint)
- {
- int i;
- for (i = 0; i < EXCEPTION_INFO_LEN; i++) {
- if (strstr(gExceptionInfo[i].name, excName)) {
- break;
- }
- }
- if (i < EXCEPTION_INFO_LEN) {
- *shouldPrint = !(gExceptionInfo[i].noPrintFlag & noPrintFlags);
- *excErrno = gExceptionInfo[i].excErrno;
- } else {
- *shouldPrint = 1;
- *excErrno = EINTERNAL;
- }
- }
- 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;
- }
|