Finish cleanup of class/field/method caching.

Change-Id: I289ae724cbd98487429275837d23b7b2d7096156
diff --git a/src/thread.cc b/src/thread.cc
index 5c221e8..d1458b2 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -1440,6 +1440,11 @@
 }
 
 void Thread::ThrowNewException(const char* exception_class_descriptor, const char* msg) {
+  CHECK(!IsExceptionPending()); // Callers should either clear or call ThrowNewWrappedException.
+  ThrowNewWrappedException(exception_class_descriptor, msg);
+}
+
+void Thread::ThrowNewWrappedException(const char* exception_class_descriptor, const char* msg) {
   // Convert "Ljava/lang/Exception;" into JNI-style "java/lang/Exception".
   CHECK_EQ('L', exception_class_descriptor[0]);
   std::string descriptor(exception_class_descriptor + 1);
@@ -1447,6 +1452,9 @@
   descriptor.erase(descriptor.length() - 1);
 
   JNIEnv* env = GetJniEnv();
+  jobject cause = env->ExceptionOccurred();
+  env->ExceptionClear();
+
   ScopedLocalRef<jclass> exception_class(env, env->FindClass(descriptor.c_str()));
   if (exception_class.get() == NULL) {
     LOG(ERROR) << "Couldn't throw new " << descriptor << " because JNI FindClass failed: "
@@ -1473,7 +1481,7 @@
     }
     return;
   }
-  int rc = env->ThrowNew(exception_class.get(), msg);
+  int rc = ::art::ThrowNewException(env, exception_class.get(), msg, cause);
   if (rc != JNI_OK) {
     LOG(ERROR) << "Couldn't throw new " << descriptor << " because JNI ThrowNew failed: "
                << PrettyTypeOf(GetException());