Fix FindFieldID to use class's classloader to find field type.
Also includes a test case, though the test case does not recreate
this exact issue because the attached native thread would need to
have a null context classloader.
Bug: 11737351
(cherry picked from 62509b662929175228bb0d0f014ef4ef4e33be10)
Change-Id: I6f15aba990eaf84696c02c37d02e80f88aff59ed
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 6a0990e..812340b 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -291,8 +291,8 @@
Class* field_type;
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
if (sig[1] != '\0') {
- ClassLoader* cl = GetClassLoader(soa);
- field_type = class_linker->FindClass(sig, cl);
+ SirtRef<mirror::ClassLoader> class_loader(soa.Self(), c->GetClassLoader());
+ field_type = class_linker->FindClass(sig, class_loader.get());
} else {
field_type = class_linker->FindPrimitiveClass(*sig);
}
diff --git a/test/JniTest/JniTest.java b/test/JniTest/JniTest.java
index 7014ef9..e368223 100644
--- a/test/JniTest/JniTest.java
+++ b/test/JniTest/JniTest.java
@@ -18,11 +18,23 @@
public static void main(String[] args) {
System.loadLibrary("arttest");
testFindClassOnAttachedNativeThread();
+ testFindFieldOnAttachedNativeThread();
testCallStaticVoidMethodOnSubClass();
}
private static native void testFindClassOnAttachedNativeThread();
+ private static boolean testFindFieldOnAttachedNativeThreadField;
+
+ private static void testFindFieldOnAttachedNativeThread() {
+ testFindFieldOnAttachedNativeThreadNative();
+ if (!testFindFieldOnAttachedNativeThreadField) {
+ throw new AssertionError();
+ }
+ }
+
+ private static native void testFindFieldOnAttachedNativeThreadNative();
+
private static void testCallStaticVoidMethodOnSubClass() {
testCallStaticVoidMethodOnSubClassNative();
if (!testCallStaticVoidMethodOnSubClass_SuperClass.executed) {
diff --git a/test/JniTest/jni_test.cc b/test/JniTest/jni_test.cc
index 72a3309..9b01453 100644
--- a/test/JniTest/jni_test.cc
+++ b/test/JniTest/jni_test.cc
@@ -67,6 +67,42 @@
assert(pthread_join_result == 0);
}
+static void* testFindFieldOnAttachedNativeThread(void*) {
+ assert(jvm != NULL);
+
+ JNIEnv* env = NULL;
+ JavaVMAttachArgs args = { JNI_VERSION_1_6, __FUNCTION__, NULL };
+ int attach_result = jvm->AttachCurrentThread(&env, &args);
+ assert(attach_result == 0);
+
+ jclass clazz = env->FindClass("JniTest");
+ assert(clazz != NULL);
+ assert(!env->ExceptionCheck());
+
+ jfieldID field = env->GetStaticFieldID(clazz, "testFindFieldOnAttachedNativeThreadField", "Z");
+ assert(field != NULL);
+ assert(!env->ExceptionCheck());
+
+ env->SetStaticBooleanField(clazz, field, JNI_TRUE);
+
+ int detach_result = jvm->DetachCurrentThread();
+ assert(detach_result == 0);
+ return NULL;
+}
+
+extern "C" JNIEXPORT void JNICALL Java_JniTest_testFindFieldOnAttachedNativeThreadNative(JNIEnv*,
+ jclass) {
+ pthread_t pthread;
+ int pthread_create_result = pthread_create(&pthread,
+ NULL,
+ testFindFieldOnAttachedNativeThread,
+ NULL);
+ assert(pthread_create_result == 0);
+ int pthread_join_result = pthread_join(pthread, NULL);
+ assert(pthread_join_result == 0);
+}
+
+
// http://b/11243757
extern "C" JNIEXPORT void JNICALL Java_JniTest_testCallStaticVoidMethodOnSubClassNative(JNIEnv* env,
jclass) {