summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/class_linker.cc21
-rw-r--r--src/dalvik_system_DexFile.cc2
-rw-r--r--src/java_lang_Class.cc14
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) {