diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/class_linker.cc | 21 | ||||
| -rw-r--r-- | src/dalvik_system_DexFile.cc | 2 | ||||
| -rw-r--r-- | src/java_lang_Class.cc | 14 |
3 files changed, 27 insertions, 10 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc index 3487af18d8..3b5ac5d084 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -1093,6 +1093,8 @@ Class* ClassLinker::FindClass(const char* descriptor, const ClassLoader* class_l return EnsureResolved(klass); } // Class is not yet loaded. + JNIEnv* env = self->GetJniEnv(); + ScopedLocalRef<jthrowable> cause(env, NULL); if (descriptor[0] == '[') { return CreateArrayClass(descriptor, class_loader); @@ -1122,7 +1124,6 @@ Class* ClassLinker::FindClass(const char* descriptor, const ClassLoader* class_l } else { std::string class_name_string(DescriptorToDot(descriptor)); ScopedThreadStateChange(self, Thread::kNative); - JNIEnv* env = self->GetJniEnv(); ScopedLocalRef<jclass> c(env, AddLocalReference<jclass>(env, GetClassRoot(kJavaLangClassLoader))); CHECK(c.get() != NULL); // TODO: cache method? @@ -1135,9 +1136,10 @@ Class* ClassLinker::FindClass(const char* descriptor, const ClassLoader* class_l ScopedLocalRef<jobject> class_loader_object(env, AddLocalReference<jobject>(env, class_loader)); ScopedLocalRef<jobject> result(env, env->CallObjectMethod(class_loader_object.get(), mid, class_name_object.get())); - if (env->ExceptionOccurred()) { - env->ExceptionClear(); // Failed to find class fall-through to NCDFE - // TODO: initialize the cause of the NCDFE to this exception + cause.reset(env->ExceptionOccurred()); + if (cause.get() != NULL) { + env->ExceptionClear(); + // Failed to find class, so fall-through to throw NCDFE. } else if (result.get() == NULL) { // broken loader - throw NPE to be compatible with Dalvik ThrowNullPointerException("ClassLoader.loadClass returned null for %s", @@ -1150,6 +1152,15 @@ Class* ClassLinker::FindClass(const char* descriptor, const ClassLoader* class_l } ThrowNoClassDefFoundError("Class %s not found", PrintableString(StringPiece(descriptor)).c_str()); + if (cause.get() != NULL) { + // Initialize the cause of the NCDFE. + ScopedLocalRef<jthrowable> ncdfe(env, env->ExceptionOccurred()); + env->ExceptionClear(); + static jclass Throwable_class = env->FindClass("java/lang/Throwable"); + static jmethodID initCause_mid = env->GetMethodID(Throwable_class, "initCause", "(Ljava/lang/Throwable;)Ljava/lang/Throwable;"); + env->CallObjectMethod(ncdfe.get(), initCause_mid, cause.get()); + env->Throw(ncdfe.get()); + } return NULL; } @@ -1449,8 +1460,6 @@ void ClassLinker::LoadMethod(const DexFile& dex_file, const ClassDataItemIterato dst->SetDexCacheResolvedFields(klass->GetDexCache()->GetResolvedFields()); dst->SetDexCacheCodeAndDirectMethods(klass->GetDexCache()->GetCodeAndDirectMethods()); dst->SetDexCacheInitializedStaticStorage(klass->GetDexCache()->GetInitializedStaticStorage()); - - // TODO: check for finalize method } void ClassLinker::AppendToBootClassPath(const DexFile& dex_file) { diff --git a/src/dalvik_system_DexFile.cc b/src/dalvik_system_DexFile.cc index a14f1241ef..85948f09d9 100644 --- a/src/dalvik_system_DexFile.cc +++ b/src/dalvik_system_DexFile.cc @@ -190,7 +190,7 @@ jclass DexFile_defineClass(JNIEnv* env, jclass, jstring javaName, jobject javaLo // method says we simply return null if the class is not found. static const char* ignored_exception_classes[] = { "java/lang/ClassNotFoundException", - "java/lang/NoClassDefFoundError" +// "java/lang/NoClassDefFoundError" }; bool clear_exception = false; for (size_t i = 0; i < arraysize(ignored_exception_classes); i++) { diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc index 0a5a9edde4..96eec2f5ec 100644 --- a/src/java_lang_Class.cc +++ b/src/java_lang_Class.cc @@ -51,11 +51,19 @@ jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean initia ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); Class* c = class_linker->FindClass(descriptor.c_str(), class_loader); if (c == NULL) { - // Convert NoClassDefFoundError to ClassNotFoundException - // TODO: chain exceptions? - DCHECK(env->ExceptionCheck()); + // Convert NoClassDefFoundError to ClassNotFoundException. + ScopedLocalRef<jthrowable> ncdfe(env, env->ExceptionOccurred()); env->ExceptionClear(); + Thread::Current()->ThrowNewException("Ljava/lang/ClassNotFoundException;", name.c_str()); + + ScopedLocalRef<jthrowable> cnfe(env, env->ExceptionOccurred()); + env->ExceptionClear(); + + static jclass Throwable_class = env->FindClass("java/lang/Throwable"); + static jmethodID initCause_mid = env->GetMethodID(Throwable_class, "initCause", "(Ljava/lang/Throwable;)Ljava/lang/Throwable;"); + env->CallObjectMethod(cnfe.get(), initCause_mid, ncdfe.get()); + env->Throw(cnfe.get()); return NULL; } if (initialize) { |