You can't call initCause on a ClassNotFoundException.

Unlike NoClassDefFoundError, ClassNotFoundException has to be constructed
with a cause, or it will stupidly set a null cause which can't then be
changed.

This patch also fixes incorrect caching of jclass local references in statics,
which I noticed while fixing the test I'd broken.

Change-Id: I017f4a4e4158554427ccb37b650c985add28980c
diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc
index 96eec2f..996d6a4 100644
--- a/src/java_lang_Class.cc
+++ b/src/java_lang_Class.cc
@@ -52,18 +52,12 @@
   Class* c = class_linker->FindClass(descriptor.c_str(), class_loader);
   if (c == NULL) {
     // Convert NoClassDefFoundError to ClassNotFoundException.
-    ScopedLocalRef<jthrowable> ncdfe(env, env->ExceptionOccurred());
+    ScopedLocalRef<jthrowable> cause(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());
+    static jclass ClassNotFoundException_class = CacheClass(env, "java/lang/ClassNotFoundException");
+    static jmethodID ctor = env->GetMethodID(ClassNotFoundException_class, "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V");
+    jthrowable cnfe = reinterpret_cast<jthrowable>(env->NewObject(ClassNotFoundException_class, ctor, javaName, cause.get()));
+    env->Throw(cnfe);
     return NULL;
   }
   if (initialize) {