diff options
| -rw-r--r-- | runtime/jni_internal.cc | 7 | ||||
| -rw-r--r-- | runtime/jni_internal_test.cc | 30 |
2 files changed, 31 insertions, 6 deletions
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc index 8842f590ca..083f179f38 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -592,7 +592,12 @@ class JNI { mirror::ArtMethod* m = soa.DecodeMethod(mid); CHECK(!kMovingMethods); jobject art_method = soa.AddLocalReference<jobject>(m); - jobject reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Method); + jobject reflect_method; + if (m->IsConstructor()) { + reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Constructor); + } else { + reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Method); + } if (env->ExceptionCheck()) { return nullptr; } diff --git a/runtime/jni_internal_test.cc b/runtime/jni_internal_test.cc index a933f86bcf..d255ec8dff 100644 --- a/runtime/jni_internal_test.cc +++ b/runtime/jni_internal_test.cc @@ -380,19 +380,39 @@ TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) { TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) { jclass jlrMethod = env_->FindClass("java/lang/reflect/Method"); + ASSERT_NE(jlrMethod, nullptr); + jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor"); + ASSERT_NE(jlrConstructor, nullptr); jclass c = env_->FindClass("java/lang/String"); ASSERT_NE(c, nullptr); - jmethodID mid = env_->GetMethodID(c, "length", "()I"); + + jmethodID mid = env_->GetMethodID(c, "<init>", "()V"); ASSERT_NE(mid, nullptr); - // Turn the mid into a java.lang.reflect.Method... + // Turn the mid into a java.lang.reflect.Constructor... jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE); - ASSERT_NE(c, nullptr); - ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod)); + ASSERT_NE(method, nullptr); + ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor)); // ...and back again. jmethodID mid2 = env_->FromReflectedMethod(method); ASSERT_NE(mid2, nullptr); // Make sure we can actually use it. - jstring s = env_->NewStringUTF("poop"); + jstring s = reinterpret_cast<jstring>(env_->AllocObject(c)); + ASSERT_NE(s, nullptr); + env_->CallVoidMethod(s, mid2); + ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck()); + + mid = env_->GetMethodID(c, "length", "()I"); + ASSERT_NE(mid, nullptr); + // Turn the mid into a java.lang.reflect.Method... + method = env_->ToReflectedMethod(c, mid, JNI_FALSE); + ASSERT_NE(method, nullptr); + ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod)); + // ...and back again. + mid2 = env_->FromReflectedMethod(method); + ASSERT_NE(mid2, nullptr); + // Make sure we can actually use it. + s = env_->NewStringUTF("poop"); + ASSERT_NE(s, nullptr); ASSERT_EQ(4, env_->CallIntMethod(s, mid2)); // Bad arguments. |