From d3333767dc25566ad207c90c897adaefd813588d Mon Sep 17 00:00:00 2001 From: Sebastien Hertz Date: Thu, 26 Jun 2014 14:45:07 +0200 Subject: Fix JNI ToReflectedMethod for constructor Returns java.lang.reflect.Constructor object for and methods. Bug: https://code.google.com/p/android/issues/detail?id=72312 Bug: 15885285 Change-Id: I2f4a266b2d9574659673dc6966104860578d709e --- runtime/jni_internal.cc | 7 ++++++- 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 8842f59..083f179 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(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 a933f86..d255ec8 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, "", "()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(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. -- cgit v1.1