summaryrefslogtreecommitdiff
path: root/test/1976-hello-structural-static-methods/src
diff options
context:
space:
mode:
Diffstat (limited to 'test/1976-hello-structural-static-methods/src')
-rw-r--r--test/1976-hello-structural-static-methods/src/Main.java21
l---------test/1976-hello-structural-static-methods/src/art/Redefinition.java1
-rw-r--r--test/1976-hello-structural-static-methods/src/art/Test1976.java203
-rw-r--r--test/1976-hello-structural-static-methods/src/art/Transform1976.java74
4 files changed, 299 insertions, 0 deletions
diff --git a/test/1976-hello-structural-static-methods/src/Main.java b/test/1976-hello-structural-static-methods/src/Main.java
new file mode 100644
index 0000000000..5abf28f25a
--- /dev/null
+++ b/test/1976-hello-structural-static-methods/src/Main.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ art.Test1976.run();
+ }
+}
diff --git a/test/1976-hello-structural-static-methods/src/art/Redefinition.java b/test/1976-hello-structural-static-methods/src/art/Redefinition.java
new file mode 120000
index 0000000000..81eaf31bbb
--- /dev/null
+++ b/test/1976-hello-structural-static-methods/src/art/Redefinition.java
@@ -0,0 +1 @@
+../../../jvmti-common/Redefinition.java \ No newline at end of file
diff --git a/test/1976-hello-structural-static-methods/src/art/Test1976.java b/test/1976-hello-structural-static-methods/src/art/Test1976.java
new file mode 100644
index 0000000000..169d2363b1
--- /dev/null
+++ b/test/1976-hello-structural-static-methods/src/art/Test1976.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package art;
+
+import java.lang.ref.*;
+import java.lang.reflect.*;
+import java.lang.invoke.*;
+import java.util.*;
+
+public class Test1976 {
+
+ // The fact that the target is having methods added makes it annoying to test since we cannot
+ // initially call them. To work around this in a simple-ish way just use (non-structural)
+ // redefinition to change the implementation of the caller of Transform1976 after redefining the
+ // target.
+ public static final class RunTransformMethods implements Runnable {
+ public void run() {
+ System.out.println("Saying everything!");
+ Transform1976.sayEverything();
+ System.out.println("Saying hi!");
+ Transform1976.sayHi();
+ }
+ }
+
+ /* Base64 encoded dex bytes of:
+ * public static final class RunTransformMethods implements Runnable {
+ * public void run() {
+ * System.out.println("Saying everything!");
+ * Transform1976.sayEverything();
+ * System.out.println("Saying hi!");
+ * Transform1976.sayHi();
+ * System.out.println("Saying bye!");
+ * Transform1976.sayBye();
+ * }
+ * }
+ */
+ public static final byte[] RUN_DEX_BYTES =
+ Base64.getDecoder()
+ .decode(
+ "ZGV4CjAzNQCv3eV8jFcpSsqMGl1ZXRk2iraZO41D0TIgBQAAcAAAAHhWNBIAAAAAAAAAAFwEAAAc"
+ + "AAAAcAAAAAsAAADgAAAAAgAAAAwBAAABAAAAJAEAAAcAAAAsAQAAAQAAAGQBAACcAwAAhAEAAAYC"
+ + "AAAOAgAAMgIAAEICAABXAgAAewIAAJsCAACyAgAAxgIAANwCAADwAgAABAMAABkDAAAmAwAAOgMA"
+ + "AEYDAABVAwAAWAMAAFwDAABpAwAAbwMAAHQDAAB9AwAAggMAAIoDAACZAwAAoAMAAKcDAAABAAAA"
+ + "AgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAAEAAAABAAAAAKAAAAAAAAABEAAAAK"
+ + "AAAAAAIAAAkABQAUAAAAAAAAAAAAAAAAAAAAFgAAAAIAAAAXAAAAAgAAABgAAAACAAAAGQAAAAUA"
+ + "AQAVAAAABgAAAAAAAAAAAAAAEQAAAAYAAAD4AQAADwAAAEwEAAAuBAAAAAAAAAEAAQABAAAA6gEA"
+ + "AAQAAABwEAYAAAAOAAMAAQACAAAA7gEAAB8AAABiAAAAGgENAG4gBQAQAHEAAwAAAGIAAAAaAQ4A"
+ + "biAFABAAcQAEAAAAYgAAABoBDABuIAUAEABxAAIAAAAOAAYADgAIAA54PHg8eDwAAQAAAAcAAAAB"
+ + "AAAACAAGPGluaXQ+ACJMYXJ0L1Rlc3QxOTc2JFJ1blRyYW5zZm9ybU1ldGhvZHM7AA5MYXJ0L1Rl"
+ + "c3QxOTc2OwATTGFydC9UcmFuc2Zvcm0xOTc2OwAiTGRhbHZpay9hbm5vdGF0aW9uL0VuY2xvc2lu"
+ + "Z0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVyQ2xhc3M7ABVMamF2YS9pby9QcmludFN0"
+ + "cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAUTGphdmEvbGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xh"
+ + "bmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07ABNSdW5UcmFuc2Zvcm1NZXRob2RzAAtTYXlp"
+ + "bmcgYnllIQASU2F5aW5nIGV2ZXJ5dGhpbmchAApTYXlpbmcgaGkhAA1UZXN0MTk3Ni5qYXZhAAFW"
+ + "AAJWTAALYWNjZXNzRmxhZ3MABG5hbWUAA291dAAHcHJpbnRsbgADcnVuAAZzYXlCeWUADXNheUV2"
+ + "ZXJ5dGhpbmcABXNheUhpAAV2YWx1ZQB2fn5EOHsiY29tcGlsYXRpb24tbW9kZSI6ImRlYnVnIiwi"
+ + "bWluLWFwaSI6MSwic2hhLTEiOiJhODM1MmYyNTQ4ODUzNjJjY2Q4ZDkwOWQzNTI5YzYwMDk0ZGQ4"
+ + "OTZlIiwidmVyc2lvbiI6IjEuNi4yMC1kZXYifQACAwEaGAECBAISBBkTFwsAAAEBAIGABIQDAQGc"
+ + "AwAAAAACAAAAHwQAACUEAABABAAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAcAAAA"
+ + "cAAAAAIAAAALAAAA4AAAAAMAAAACAAAADAEAAAQAAAABAAAAJAEAAAUAAAAHAAAALAEAAAYAAAAB"
+ + "AAAAZAEAAAEgAAACAAAAhAEAAAMgAAACAAAA6gEAAAEQAAACAAAA+AEAAAIgAAAcAAAABgIAAAQg"
+ + "AAACAAAAHwQAAAAgAAABAAAALgQAAAMQAAACAAAAPAQAAAYgAAABAAAATAQAAAAQAAABAAAAXAQA"
+ + "AA==");
+
+ public static void run() throws Exception {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+ doTest();
+ }
+
+ private static final boolean PRINT_ID_NUM = false;
+
+ public static void printRun(long id, Method m) {
+ if (PRINT_ID_NUM) {
+ System.out.println("Running method " + id + " " + m + " using JNI.");
+ } else {
+ System.out.println("Running method " + m + " using JNI.");
+ }
+ }
+
+ public static final class MethodHandleWrapper {
+ private MethodHandle mh;
+ private Method m;
+ public MethodHandleWrapper(MethodHandle mh, Method m) {
+ this.m = m;
+ this.mh = mh;
+ }
+ public MethodHandle getHandle() {
+ return mh;
+ }
+ public Method getMethod() {
+ return m;
+ }
+ public Object invoke() throws Throwable {
+ return mh.invoke();
+ }
+ public String toString() {
+ return mh.toString();
+ }
+ }
+
+ public static MethodHandleWrapper[] getMethodHandles(Method[] methods) throws Exception {
+ final MethodHandles.Lookup l = MethodHandles.lookup();
+ ArrayList<MethodHandleWrapper> res = new ArrayList<>();
+ for (Method m : methods) {
+ if (!Modifier.isStatic(m.getModifiers())) {
+ continue;
+ }
+ res.add(new MethodHandleWrapper(l.unreflect(m), m));
+ }
+ return res.toArray(new MethodHandleWrapper[0]);
+ }
+
+ public static void runMethodHandles(MethodHandleWrapper[] handles) throws Exception {
+ for (MethodHandleWrapper h : handles) {
+ try {
+ System.out.println("Invoking " + h + " (" + h.getMethod() + ")");
+ h.invoke();
+ } catch (Throwable t) {
+ if (t instanceof Exception) {
+ throw (Exception)t;
+ } else if (t instanceof Error) {
+ throw (Error)t;
+ } else {
+ throw new RuntimeException("Unexpected throwable thrown!", t);
+ }
+ }
+ }
+ }
+
+ public static void doTest() throws Exception {
+ Runnable r = new RunTransformMethods();
+ System.out.println("Running directly");
+ r.run();
+ System.out.println("Running reflective");
+ Method[] methods = Transform1976.class.getDeclaredMethods();
+ for (Method m : methods) {
+ if (Modifier.isStatic(m.getModifiers())) {
+ System.out.println("Reflectively invoking " + m);
+ m.invoke(null);
+ } else {
+ System.out.println("Not invoking non-static method " + m);
+ }
+ }
+ System.out.println("Running jni");
+ long[] mids = getMethodIds(methods);
+ callNativeMethods(Transform1976.class, mids);
+ MethodHandleWrapper[] handles = getMethodHandles(methods);
+ System.out.println("Running method handles");
+ runMethodHandles(handles);
+ Redefinition.doCommonStructuralClassRedefinition(
+ Transform1976.class, Transform1976.REDEFINED_DEX_BYTES);
+ // Change RunTransformMethods to also call the 'runBye' method. No RI support so no classfile
+ // bytes required.
+ Redefinition.doCommonClassRedefinition(RunTransformMethods.class, new byte[] {}, RUN_DEX_BYTES);
+ System.out.println("Running directly after redef");
+ r.run();
+ System.out.println("Running reflective after redef using old j.l.r.Method");
+ for (Method m : methods) {
+ if (Modifier.isStatic(m.getModifiers())) {
+ System.out.println("Reflectively invoking " + m + " on old j.l.r.Method");
+ m.invoke(null);
+ } else {
+ System.out.println("Not invoking non-static method " + m);
+ }
+ }
+ System.out.println("Running reflective after redef using new j.l.r.Method");
+ for (Method m : Transform1976.class.getDeclaredMethods()) {
+ if (Modifier.isStatic(m.getModifiers())) {
+ System.out.println("Reflectively invoking " + m + " on new j.l.r.Method");
+ m.invoke(null);
+ } else {
+ System.out.println("Not invoking non-static method " + m);
+ }
+ }
+ System.out.println("Running jni with old ids");
+ callNativeMethods(Transform1976.class, mids);
+ System.out.println("Running jni with new ids");
+ callNativeMethods(Transform1976.class, getMethodIds(Transform1976.class.getDeclaredMethods()));
+
+ System.out.println("Running method handles using old handles");
+ runMethodHandles(handles);
+ System.out.println("Running method handles using new handles");
+ runMethodHandles(getMethodHandles(Transform1976.class.getDeclaredMethods()));
+ }
+
+ public static native long[] getMethodIds(Method[] m);
+
+ public static native void callNativeMethods(Class<?> k, long[] smethods);
+}
diff --git a/test/1976-hello-structural-static-methods/src/art/Transform1976.java b/test/1976-hello-structural-static-methods/src/art/Transform1976.java
new file mode 100644
index 0000000000..e347711ff6
--- /dev/null
+++ b/test/1976-hello-structural-static-methods/src/art/Transform1976.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package art;
+
+import java.util.Base64;
+
+public class Transform1976 {
+
+ static {
+ }
+
+ /* Dex file for:
+ * package art;
+ * public class Transform1976 {
+ * static {}
+ * public static byte[] REDEFINED_DEX_BYTES;
+ * public static void sayEverything() {
+ * sayHi();
+ * sayBye();
+ * }
+ * public static void sayBye() {
+ * System.out.println("Bye");
+ * }
+ * public static void sayHi() {
+ * System.out.println("Not saying hi again!");
+ * }
+ * }
+ */
+ public static byte[] REDEFINED_DEX_BYTES =
+ Base64.getDecoder()
+ .decode(
+ "ZGV4CjAzNQBHoxOnl1VNY5YvAENBMpZs9rgNOtJjgZFEBAAAcAAAAHhWNBIAAAAAAAAAAJgDAAAU"
+ + "AAAAcAAAAAcAAADAAAAAAgAAANwAAAACAAAA9AAAAAcAAAAEAQAAAQAAADwBAADoAgAAXAEAAAYC"
+ + "AAAQAgAAGAIAAB0CAAAyAgAASQIAAF0CAABxAgAAhQIAAJsCAACwAgAAxAIAAMcCAADLAgAAzwIA"
+ + "ANQCAADdAgAA5QIAAPQCAAD7AgAAAwAAAAQAAAAFAAAABgAAAAcAAAALAAAADQAAAAsAAAAFAAAA"
+ + "AAAAAAwAAAAFAAAAAAIAAAAABgAJAAAABAABAA4AAAAAAAAAAAAAAAAAAAABAAAAAAAAABAAAAAA"
+ + "AAAAEQAAAAAAAAASAAAAAQABAA8AAAACAAAAAQAAAAAAAAABAAAAAgAAAAAAAAAKAAAAAAAAAHMD"
+ + "AAAAAAAAAAAAAAAAAADoAQAAAQAAAA4AAAABAAEAAQAAAOwBAAAEAAAAcBAGAAAADgACAAAAAgAA"
+ + "APABAAAIAAAAYgABABoBAgBuIAUAEAAOAAAAAAAAAAAA9QEAAAcAAABxAAQAAABxAAIAAAAOAAAA"
+ + "AgAAAAIAAAD7AQAACAAAAGIAAQAaAQgAbiAFABAADgADAA4AAgAOAAoADngABgAOPDwADQAOeAAB"
+ + "AAAAAwAIPGNsaW5pdD4ABjxpbml0PgADQnllABNMYXJ0L1RyYW5zZm9ybTE5NzY7ABVMamF2YS9p"
+ + "by9QcmludFN0cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJM"
+ + "amF2YS9sYW5nL1N5c3RlbTsAFE5vdCBzYXlpbmcgaGkgYWdhaW4hABNSRURFRklORURfREVYX0JZ"
+ + "VEVTABJUcmFuc2Zvcm0xOTc2LmphdmEAAVYAAlZMAAJbQgADb3V0AAdwcmludGxuAAZzYXlCeWUA"
+ + "DXNheUV2ZXJ5dGhpbmcABXNheUhpAHZ+fkQ4eyJjb21waWxhdGlvbi1tb2RlIjoiZGVidWciLCJt"
+ + "aW4tYXBpIjoxLCJzaGEtMSI6ImE4MzUyZjI1NDg4NTM2MmNjZDhkOTA5ZDM1MjljNjAwOTRkZDg5"
+ + "NmUiLCJ2ZXJzaW9uIjoiMS42LjIwLWRldiJ9AAEABQAACQCIgATcAgGBgATwAgEJiAMBCagDAQnI"
+ + "AwAAAAAAAAAOAAAAAAAAAAEAAAAAAAAAAQAAABQAAABwAAAAAgAAAAcAAADAAAAAAwAAAAIAAADc"
+ + "AAAABAAAAAIAAAD0AAAABQAAAAcAAAAEAQAABgAAAAEAAAA8AQAAASAAAAUAAABcAQAAAyAAAAUA"
+ + "AADoAQAAARAAAAEAAAAAAgAAAiAAABQAAAAGAgAAACAAAAEAAABzAwAAAxAAAAEAAACUAwAAABAA"
+ + "AAEAAACYAwAA");
+
+ public static void sayEverything() {
+ sayHi();
+ }
+
+ public static void sayHi() {
+ System.out.println("hello");
+ }
+}