diff -r b09e56145e11 test/jdk/java/lang/instrument/NamedBuffer.java --- a/test/jdk/java/lang/instrument/NamedBuffer.java Thu Mar 08 04:23:31 2018 +0000 +++ b/test/jdk/java/lang/instrument/NamedBuffer.java Mon Jan 07 18:16:52 2019 -0800 @@ -64,7 +64,7 @@ public static byte[] loadBufferFromStream(InputStream stream) throws IOException - { + { // hack for now, just assume the stream will fit in our reasonable size buffer. // if not, panic int bufferLimit = 200 * 1024; @@ -83,5 +83,53 @@ 0, actualSize); return resultBuffer; + } + + static final String DEST = System.getProperty("test.classes"); + static final boolean VERBOSE = false; + + static boolean checkMatch(byte[] buf, byte[] name, int begIdx) { + for (int i = 0; i < name.length; i++) { + if (buf[i + begIdx] != name[i]) { + return false; + } } + return true; + } + + static byte[] + bytesForHostClass(char replace, String className) throws Throwable { + String tail = className.substring(1); + String origClassName = "" + replace + tail; + File clsfile = new File(DEST + "/" + origClassName + ".class"); + + if (VERBOSE) { + System.out.println(" Reading bytes from " + clsfile); + } + byte[] buf = null; + try (FileInputStream str = new FileInputStream(clsfile)) { + buf = loadBufferFromStream(str); + } + System.out.println("\n Changing name of " + origClassName + " to " + className + " in bytes"); + + boolean found = false; + int dollarSignIdx = className.indexOf('$'); + int ptrnLen = (dollarSignIdx == -1) ? className.length() : dollarSignIdx; + byte[] ptrnBytes = origClassName.substring(0, ptrnLen).getBytes(); + final byte FirstByte = className.getBytes()[0]; + + for (int i = 0; i < buf.length - ptrnLen; i++) { + if(checkMatch(buf, ptrnBytes, i)) { + if (VERBOSE) { + System.out.println("Appear to have found " + origClassName + " starting at " + i); + } + buf[i] = FirstByte; + found = true; + } + } + if (!found) { + throw new Error("Could not locate '" + ptrnBytes + "' name in byte array"); + } + return buf; + } } diff -r b09e56145e11 test/jdk/java/lang/instrument/RedefineInterfaceMethods/RedefineInterfaceMethods.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineInterfaceMethods/RedefineInterfaceMethods.java Mon Jan 07 18:16:52 2019 -0800 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8191496 + * @summary Crash in JVM_GetClassModifiers when redefining a class' private method during resolution of the bootstrap specifier + * @library /test/lib + * @modules java.base/jdk.internal.misc + * @modules java.compiler + * java.instrument + * jdk.jartool/sun.tools.jar + * @compile ../NamedBuffer.java + * @compile redef/Xost.java + * @run main RedefineClassHelper + * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class*=trace RedefineInterfaceMethods + */ + +class Host { + static void log(String msg) { System.out.println(msg); } + + static interface B { + int ORIGINAL_RETURN = 1; + int NEW_RETURN = 2; + + private int privateMethod() { + Runnable race1 = () -> log("Hello from inside privateMethod"); + race1.run(); + return ORIGINAL_RETURN; + } + + public default int defaultMethod(String p) { + log(p + "from interface B's defaultMethod"); + return privateMethod(); + } + } + + static class Impl implements B { + } +} + +public class RedefineInterfaceMethods { + private static byte[] bytesForHostClass(char replace) throws Throwable { + return NamedBuffer.bytesForHostClass(replace, "Host$B"); + } + + public static void main(String[] args) throws Throwable { + Host.Impl impl = new Host.Impl(); + + int res = impl.defaultMethod("Hello "); + if (res != Host.B.ORIGINAL_RETURN) + throw new Error("defaultMethod returned " + res + + " expected " + Host.B.ORIGINAL_RETURN); + + byte[] buf = bytesForHostClass('X'); + RedefineClassHelper.redefineClass(Host.B.class, buf); + + res = impl.defaultMethod("Goodbye "); + if (res != Host.B.NEW_RETURN) + throw new Error("defaultMethod returned " + res + + " expected " + Host.B.NEW_RETURN); + } +} diff -r b09e56145e11 test/jdk/java/lang/instrument/RedefineInterfaceMethods/redef/Xost.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineInterfaceMethods/redef/Xost.java Mon Jan 07 18:16:52 2019 -0800 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +class Xost { + static void log(String msg) { System.out.println(msg); } + + static interface B { + int ORIGINAL_RETURN = 1; + int NEW_RETURN = 2; + + private int privateMethod() { + Runnable race1 = () -> log("Hello from inside privateMethod"); + race1.run(); + return NEW_RETURN; + } + public default int defaultMethod(String p) { + log(p + "from interface B's defaultMethod"); + return privateMethod(); + } + } + + static class Impl implements B { + } +} diff -r b09e56145e11 test/jdk/java/lang/instrument/RedefineMathTesterMethods/RedefineMathTesterMethods.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineMathTesterMethods/RedefineMathTesterMethods.java Mon Jan 07 18:16:52 2019 -0800 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8191496 + * @summary Crash in JVM_GetClassModifiers when redefining a class' private method during resolution of the bootstrap specifier + * @library /test/lib + * @modules java.base/jdk.internal.misc + * @modules java.compiler + * java.instrument + * jdk.jartool/sun.tools.jar + * @compile ../NamedBuffer.java + * @compile redef/Xost.java + * @run main RedefineClassHelper + * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class*=trace RedefineMathTesterMethods + */ + +interface MathOperation { + public int operation(int a, int b); +} + +class Host { + static class B { + public static int operate(int a, int b, MathOperation mathOperation) { + return mathOperation.operation(a, b); + } + + static int test_math() { + MathOperation addition = (int a, int b) -> a + b; + return operate(10, 5, addition); + } + } +} + +public class RedefineMathTesterMethods { + private static byte[] bytesForHostClass(char replace) throws Throwable { + return NamedBuffer.bytesForHostClass(replace, "Host$B"); + } + + public static void main(String[] args) throws Throwable { + int res = Host.B.test_math(); + System.out.println("Result = " + res); + if (res != 15) { + throw new Error("test_math returned " + res + " expected " + 15); + } + + byte[] buf = bytesForHostClass('X'); + RedefineClassHelper.redefineClass(Host.B.class, buf); + + res = Host.B.test_math(); + if (res != 5) + throw new Error("test_math returned " + res + " expected " + 5); + } +} diff -r b09e56145e11 test/jdk/java/lang/instrument/RedefineMathTesterMethods/redef/Xost.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineMathTesterMethods/redef/Xost.java Mon Jan 07 18:16:52 2019 -0800 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +interface MathOperation { + public int operation(int a, int b); +} + +class Xost { + static class B { + public static int operate(int a, int b, MathOperation mathOperation) { + return mathOperation.operation(a, b); + } + + static int test_math() { + MathOperation subtraction = (int a, int b) -> a - b; + return operate(10, 5, subtraction); + } + } +}