diff options
| author | 2017-08-30 01:14:16 +0000 | |
|---|---|---|
| committer | 2017-08-30 01:14:16 +0000 | |
| commit | 4ec99d1e710649fb56f03d216cb6a5d69e7ecd7d (patch) | |
| tree | 222a4a9677d0355cc82abedf591cd3e399eead11 | |
| parent | 8877f4cc9a0dcfd08eef259bafea7e5b08fd1fc7 (diff) | |
| parent | 35f1d087ecccbb80df75f89890e9da1f2c59053b (diff) | |
Merge "test: Add JNI test to check for <clinit> method lookup"
| -rwxr-xr-x | test/004-JniTest/build | 26 | ||||
| -rw-r--r-- | test/004-JniTest/expected.txt | 2 | ||||
| -rw-r--r-- | test/004-JniTest/jni_test.cc | 12 | ||||
| -rw-r--r-- | test/004-JniTest/src/Main.java | 32 |
4 files changed, 72 insertions, 0 deletions
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: <NSME Exception> +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, "<clinit>", "()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 <NSME Exception> + try { + System.out.println("Clinit Lookup: ClassWithoutClinit: " + methodString(lookupClinit(ClassWithoutClinit.class))); + } catch (NoSuchMethodError e) { + System.out.println("Clinit Lookup: ClassWithoutClinit: <NSME Exception>"); + } + // Expect this to print <clinit> + try { + System.out.println("Clinit Lookup: ClassWithClinit: " + methodString(lookupClinit(ClassWithClinit.class))); + } catch (NoSuchMethodError e) { + System.out.println("Clinit Lookup: ClassWithClinit: <NSME Exception>"); + } + } + + private static String methodString(java.lang.reflect.Executable method) { + if (method == null) { + return "<<null>>"; + } 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 |