|
32 | 32 | * @run main/othervm -javaagent:redefineagent.jar ClassVersionAfterRedefine |
33 | 33 | */ |
34 | 34 |
|
35 | | -import java.io.InputStream; |
36 | 35 | import java.lang.reflect.Method; |
37 | 36 |
|
38 | 37 | import static jdk.test.lib.Asserts.assertTrue; |
39 | 38 |
|
40 | 39 | public class ClassVersionAfterRedefine extends ClassLoader { |
41 | 40 |
|
42 | | - private static String myName = ClassVersionAfterRedefine.class.getName(); |
43 | | - |
44 | | - private static byte[] getBytecodes(String name) throws Exception { |
45 | | - InputStream is = ClassVersionAfterRedefine.class.getResourceAsStream(name + ".class"); |
46 | | - byte[] buf = is.readAllBytes(); |
47 | | - System.out.println("sizeof(" + name + ".class) == " + buf.length); |
48 | | - return buf; |
49 | | - } |
50 | | - |
51 | | - private static int getStringIndex(String needle, byte[] buf) { |
52 | | - return getStringIndex(needle, buf, 0); |
53 | | - } |
54 | | - |
55 | | - private static int getStringIndex(String needle, byte[] buf, int offset) { |
56 | | - outer: |
57 | | - for (int i = offset; i < buf.length - offset - needle.length(); i++) { |
58 | | - for (int j = 0; j < needle.length(); j++) { |
59 | | - if (buf[i + j] != (byte)needle.charAt(j)) continue outer; |
60 | | - } |
61 | | - return i; |
62 | | - } |
63 | | - return 0; |
64 | | - } |
65 | | - |
66 | | - private static void replaceString(byte[] buf, String name, int index) { |
67 | | - for (int i = index; i < index + name.length(); i++) { |
68 | | - buf[i] = (byte)name.charAt(i - index); |
69 | | - } |
70 | | - } |
71 | | - |
72 | | - private static void replaceAllStrings(byte[] buf, String oldString, String newString) throws Exception { |
73 | | - assertTrue(oldString.length() == newString.length(), "must have same length"); |
74 | | - int index = -1; |
75 | | - while ((index = getStringIndex(oldString, buf, index + 1)) != 0) { |
76 | | - replaceString(buf, newString, index); |
77 | | - } |
78 | | - } |
79 | | - |
80 | 41 | public static void main(String[] s) throws Exception { |
81 | 42 |
|
82 | | - byte[] buf = getBytecodes("TestClassOld"); |
83 | | - // Poor man's renaming of class "TestClassOld" to "TestClassXXX" |
84 | | - replaceAllStrings(buf, "TestClassOld", "TestClassXXX"); |
85 | 43 | ClassVersionAfterRedefine cvar = new ClassVersionAfterRedefine(); |
| 44 | + |
| 45 | + byte[] buf = RedefineClassHelper.replaceClassName(cvar, "TestClassOld", "TestClassXXX"); |
86 | 46 | Class<?> old = cvar.defineClass(null, buf, 0, buf.length); |
87 | 47 | Method foo = old.getMethod("foo"); |
88 | 48 | Object result = foo.invoke(null); |
89 | 49 | assertTrue("java-lang-String".equals(result)); |
90 | 50 | System.out.println(old.getSimpleName() + ".foo() = " + result); |
91 | 51 |
|
92 | | - buf = getBytecodes("TestClassNew"); |
93 | 52 | // Rename class "TestClassNew" to "TestClassXXX" so we can use it for |
94 | 53 | // redefining the original version of "TestClassXXX" (i.e. "TestClassOld"). |
95 | | - replaceAllStrings(buf, "TestClassNew", "TestClassXXX"); |
96 | | - // Now redine the original version of "TestClassXXX" (i.e. "TestClassOld"). |
| 54 | + buf = RedefineClassHelper.replaceClassName(cvar, "TestClassNew", "TestClassXXX"); |
| 55 | + // Now redefine the original version of "TestClassXXX" (i.e. "TestClassOld"). |
97 | 56 | RedefineClassHelper.redefineClass(old, buf); |
98 | 57 | result = foo.invoke(null); |
99 | 58 | assertTrue("java.lang.String".equals(result)); |
|
0 commit comments