static void wrapClassNotFoundException(Env* env, const char* className) { Object* exception = rvmExceptionOccurred(env); if (exception && exception->clazz == java_lang_ClassNotFoundException) { // If ClassNotFoundException is thrown we have to wrap it in a NoClassDefFoundError exception = rvmExceptionClear(env); Method* constructor = rvmGetInstanceMethod(env, java_lang_NoClassDefFoundError, "<init>", "(Ljava/lang/String;)V"); if (!constructor) return; Object* message = rvmNewStringUTF(env, className, -1); if (!message) return; Object* wrappedException = rvmNewObject(env, java_lang_NoClassDefFoundError, constructor, message); if (!wrappedException) return; Class* java_lang_StackTraceElement = rvmFindClassUsingLoader(env, "java/lang/StackTraceElement", NULL); if (!java_lang_StackTraceElement) return; ObjectArray* stackTrace = rvmNewObjectArray(env, 0, java_lang_StackTraceElement, NULL, NULL); if (!stackTrace) return; Method* setStackTrace = rvmGetInstanceMethod(env, java_lang_Throwable, "setStackTrace", "([Ljava/lang/StackTraceElement;)V"); if (!setStackTrace) return; rvmCallVoidInstanceMethod(env, wrappedException, setStackTrace, stackTrace); if (rvmExceptionCheck(env)) return; Method* initCause = rvmGetInstanceMethod(env, java_lang_NoClassDefFoundError, "initCause", "(Ljava/lang/Throwable;)Ljava/lang/Throwable;"); if (!initCause) return; rvmCallObjectInstanceMethod(env, wrappedException, initCause, exception); if (!rvmExceptionCheck(env)) rvmThrow(env, wrappedException); } }
Class* rvmFindClassUsingLoader(Env* env, const char* className, ClassLoader* classLoader) { if (!classLoader || classLoader->parent == NULL) { // This is the bootstrap classloader. No need to call ClassLoader.loadClass() return findBootClass(env, className); } char* binaryClassName = rvmToBinaryClassName(env, className); if (!binaryClassName) return NULL; Object* binaryClassNameString = rvmNewInternedStringUTF(env, binaryClassName, -1); if (!binaryClassNameString) return NULL; Method* loadClassMethod = rvmGetInstanceMethod(env, java_lang_ClassLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); if (!loadClassMethod) return NULL; Object* clazz = rvmCallObjectInstanceMethod(env, (Object*) classLoader, loadClassMethod, binaryClassNameString); if (rvmExceptionOccurred(env)) return NULL; return (Class*) clazz; }
static void threadExitUncaughtException(Env* env, Thread* thread) { Object* throwable = rvmExceptionClear(env); Object* handler = rvmCallObjectInstanceMethod(env, (Object*) thread->threadObj, getUncaughtExceptionHandlerMethod); // Ignore exception thrown by getUncaughtException() rvmExceptionClear(env); if (!handler) { handler = thread->threadObj->group; } if (handler) { rvmCallVoidInstanceMethod(env, handler, uncaughtExceptionMethod, (Object*) thread->threadObj, throwable); } else { rvmPrintStackTrace(env, throwable); } // Ignore exception thrown by uncaughtException() or rvmPrintStackTrace() rvmExceptionClear(env); }