test: Add JNI test to check for <clinit> method lookup
Bug: 65059445
Change-Id: I03cd36466cf1edd5c64607542185e2cfd8b47ba5
diff --git a/test/004-JniTest/build b/test/004-JniTest/build
index c8440fc..e563d73 100755
--- a/test/004-JniTest/build
+++ b/test/004-JniTest/build
@@ -38,4 +38,30 @@
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 f7e404d..7e85ab1 100644
--- a/test/004-JniTest/expected.txt
+++ b/test/004-JniTest/expected.txt
@@ -58,3 +58,5 @@
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 a34d633..bc5a0a6 100644
--- a/test/004-JniTest/jni_test.cc
+++ b/test/004-JniTest/jni_test.cc
@@ -776,6 +776,18 @@
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 0c4ed89..fe5f4e3 100644
--- a/test/004-JniTest/src/Main.java
+++ b/test/004-JniTest/src/Main.java
@@ -56,6 +56,8 @@
registerNativesJniTest();
testFastNativeMethods();
testCriticalNativeMethods();
+
+ testClinitMethodLookup();
}
private static native boolean registerNativesJniTest();
@@ -314,6 +316,36 @@
}
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