Have JNI FindClass fall back to system ClassLoader
Bug: 10994325
Change-Id: Id0a46e78eecfe8a9eb91008765c4fff48697cc58
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 0a00284..6a0990e 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -255,11 +255,28 @@
static ClassLoader* GetClassLoader(const ScopedObjectAccess& soa)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ArtMethod* method = soa.Self()->GetCurrentMethod(NULL);
- if (method == NULL ||
- method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
+ // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
+ if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
return soa.Self()->GetClassLoaderOverride();
}
- return method->GetDeclaringClass()->GetClassLoader();
+ // If we have a method, use its ClassLoader for context.
+ if (method != NULL) {
+ return method->GetDeclaringClass()->GetClassLoader();
+ }
+ // We don't have a method, so try to use the system ClassLoader.
+ ClassLoader* class_loader = soa.Decode<ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
+ if (class_loader != NULL) {
+ return class_loader;
+ }
+ // See if the override ClassLoader is set for gtests.
+ class_loader = soa.Self()->GetClassLoaderOverride();
+ if (class_loader != NULL) {
+ // If so, CommonTest should have set UseCompileTimeClassPath.
+ CHECK(Runtime::Current()->UseCompileTimeClassPath());
+ return class_loader;
+ }
+ // Use the BOOTCLASSPATH.
+ return NULL;
}
static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
@@ -2101,13 +2118,14 @@
descriptor += ClassHelper(element_class).GetDescriptor();
// Find the class.
- ScopedLocalRef<jclass> java_array_class(env, FindClass(env, descriptor.c_str()));
- if (java_array_class.get() == NULL) {
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ Class* array_class = class_linker->FindClass(descriptor.c_str(),
+ element_class->GetClassLoader());
+ if (array_class == NULL) {
return NULL;
}
// Allocate and initialize if necessary.
- Class* array_class = soa.Decode<Class*>(java_array_class.get());
ObjectArray<Object>* result = ObjectArray<Object>::Alloc(soa.Self(), array_class, length);
if (initial_element != NULL) {
Object* initial_object = soa.Decode<Object*>(initial_element);