From 35f1d087ecccbb80df75f89890e9da1f2c59053b Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Tue, 29 Aug 2017 13:50:13 -0700 Subject: test: Add JNI test to check for method lookup Bug: 65059445 Change-Id: I03cd36466cf1edd5c64607542185e2cfd8b47ba5 --- test/004-JniTest/build | 26 ++++++++++++++++++++++++++ test/004-JniTest/expected.txt | 2 ++ test/004-JniTest/jni_test.cc | 12 ++++++++++++ test/004-JniTest/src/Main.java | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/test/004-JniTest/build b/test/004-JniTest/build index c8440fcb73..e563d734c2 100755 --- a/test/004-JniTest/build +++ b/test/004-JniTest/build @@ -38,4 +38,30 @@ function javac_wrapper { export -f javac_wrapper export JAVAC=javac_wrapper +###################################################################### + +# Use the original dx with no extra magic or pessimizing flags. +# This ensures that any default optimizations that dx do would not break JNI. + +export ORIGINAL_DX="$DX" + +# Filter out --debug flag from dx. +function dx_wrapper { + local args=("$@") + local args_filtered=() + for i in "${args[@]}"; do + case "$i" in + --debug) + ;; + *) + args_filtered+=("$i") + ;; + esac + done + "$ORIGINAL_DX" "${args_filtered[@]}" +} + +export -f dx_wrapper +export DX=dx_wrapper + ./default-build "$@" diff --git a/test/004-JniTest/expected.txt b/test/004-JniTest/expected.txt index f7e404d30b..7e85ab1041 100644 --- a/test/004-JniTest/expected.txt +++ b/test/004-JniTest/expected.txt @@ -58,3 +58,5 @@ EXCEPTION OCCURED: java.lang.IncompatibleClassChangeError: Conflicting default m hi-lambda: λ hi-default δλ hi-default δλ +Clinit Lookup: ClassWithoutClinit: +Clinit Lookup: ClassWithClinit: Main$ClassWithClinit()(Class: class java.lang.reflect.Constructor) diff --git a/test/004-JniTest/jni_test.cc b/test/004-JniTest/jni_test.cc index a34d633590..bc5a0a64e8 100644 --- a/test/004-JniTest/jni_test.cc +++ b/test/004-JniTest/jni_test.cc @@ -776,6 +776,18 @@ static jint Java_Main_intCriticalNativeMethod(jint a, jint b, jint c) { return a + b + c; } +extern "C" JNIEXPORT jobject JNICALL Java_Main_lookupClinit(JNIEnv* env, jclass, jclass kls) { + jmethodID clinit_id = env->GetStaticMethodID(kls, "", "()V"); + + if (clinit_id != nullptr) { + jobject obj = env->ToReflectedMethod(kls, clinit_id, /*isStatic*/ true); + CHECK(obj != nullptr); + return obj; + } else { + return nullptr; + } +} + extern "C" JNIEXPORT jboolean JNICALL Java_Main_isSlowDebug(JNIEnv*, jclass) { // Return whether slow-debug is on. Only relevant for debug builds. if (kIsDebugBuild) { diff --git a/test/004-JniTest/src/Main.java b/test/004-JniTest/src/Main.java index 0c4ed89f81..fe5f4e3dc6 100644 --- a/test/004-JniTest/src/Main.java +++ b/test/004-JniTest/src/Main.java @@ -56,6 +56,8 @@ public class Main { registerNativesJniTest(); testFastNativeMethods(); testCriticalNativeMethods(); + + testClinitMethodLookup(); } private static native boolean registerNativesJniTest(); @@ -314,6 +316,36 @@ public class Main { } private static native boolean isSlowDebug(); + + private static void testClinitMethodLookup() { + // Expect this to print + try { + System.out.println("Clinit Lookup: ClassWithoutClinit: " + methodString(lookupClinit(ClassWithoutClinit.class))); + } catch (NoSuchMethodError e) { + System.out.println("Clinit Lookup: ClassWithoutClinit: "); + } + // Expect this to print + try { + System.out.println("Clinit Lookup: ClassWithClinit: " + methodString(lookupClinit(ClassWithClinit.class))); + } catch (NoSuchMethodError e) { + System.out.println("Clinit Lookup: ClassWithClinit: "); + } + } + + private static String methodString(java.lang.reflect.Executable method) { + if (method == null) { + return "<>"; + } else { + return method.toString() + "(Class: " + method.getClass().toString() + ")"; + } + } + private static native java.lang.reflect.Executable lookupClinit(Class kls); + + private static class ClassWithoutClinit { + } + private static class ClassWithClinit { + static {} + } } @FunctionalInterface -- cgit v1.2.3-59-g8ed1b