Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/test/java/lang/instrument/VerifyLocalVariableTableOnRetransformTest.java
+++ new/test/java/lang/instrument/VerifyLocalVariableTableOnRetransformTest.java
1 1 /*
2 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation.
8 8 *
9 9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 12 * version 2 for more details (a copy is included in the LICENSE file that
13 13 * accompanied this code).
14 14 *
15 15 * You should have received a copy of the GNU General Public License version
16 16 * 2 along with this work; if not, write to the Free Software Foundation,
17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 18 *
19 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 20 * or visit www.oracle.com if you need additional information or have any
21 21 * questions.
22 22 */
23 23
24 24 import java.io.*;
25 25 import java.lang.instrument.Instrumentation;
26 26 import java.lang.instrument.ClassFileTransformer;
27 27 import java.net.*;
28 28 import java.security.ProtectionDomain;
29 29
30 30 public class
31 31 VerifyLocalVariableTableOnRetransformTest
32 32 extends ATransformerManagementTestCase
33 33 {
34 34 private byte[] fTargetClassBytes;
35 35 private boolean fTargetClassMatches;
36 36 private String fTargetClassName = "DummyClassWithLVT";
37 37 private boolean fTargetClassSeen;
38 38
39 39 /**
40 40 * Constructor for VerifyLocalVariableTableOnRetransformTest.
41 41 * @param name
42 42 */
43 43 public VerifyLocalVariableTableOnRetransformTest(String name)
44 44 {
45 45 super(name);
46 46
47 47 String resourceName = fTargetClassName + ".class";
48 48 File f = new File(System.getProperty("test.classes", "."), resourceName);
49 49 System.out.println("Reading test class from " + f);
50 50 try
51 51 {
52 52 InputStream redefineStream = new FileInputStream(f);
53 53 fTargetClassBytes = NamedBuffer.loadBufferFromStream(redefineStream);
54 54 System.out.println("Read " + fTargetClassBytes.length + " bytes.");
55 55 }
56 56 catch (IOException e)
57 57 {
58 58 fail("Could not load the class: "+resourceName);
59 59 }
60 60 }
61 61
62 62 public static void
63 63 main (String[] args)
64 64 throws Throwable {
65 65 ATestCaseScaffold test = new VerifyLocalVariableTableOnRetransformTest(args[0]);
66 66 test.runTest();
67 67 }
68 68
69 69 protected final void
70 70 doRunTest()
71 71 throws Throwable {
72 72 verifyClassFileBuffer();
73 73 }
74 74
75 75 public void
76 76 verifyClassFileBuffer()
77 77 throws Throwable
78 78 {
79 79 beVerbose();
80 80
81 81 // With this call here, we will see the target class twice:
82 82 // first when it gets loaded and second when it gets retransformed.
83 83 addTransformerToManager(fInst, new MyObserver(), true);
84 84
85 85 ClassLoader loader = getClass().getClassLoader();
86 86
87 87 Class target = loader.loadClass(fTargetClassName);
88 88 assertEquals(fTargetClassName, target.getName());
89 89
90 90 // make an instance to prove the class was really loaded
91 91 Object testInstance = target.newInstance();
92 92
↓ open down ↓ |
92 lines elided |
↑ open up ↑ |
93 93 // With this call here, we will see the target class once:
94 94 // when it gets retransformed.
95 95 //addTransformerToManager(fInst, new MyObserver(), true);
96 96
97 97 assertTrue(fTargetClassName + " was not seen by transform()",
98 98 fTargetClassSeen);
99 99
100 100 // The HotSpot VM hands us class file bytes at initial class
101 101 // load time that match the .class file contents. However,
102 102 // according to the following spec that is not required:
103 - // http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html#retransformClasses(java.lang.Class...)
103 + // https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html#retransformClasses(java.lang.Class...)
104 104 // This test exists to catch any unintentional change in
105 105 // behavior by the HotSpot VM. If this behavior is intentionally
106 106 // changed in the future, then this test will need to be
107 107 // updated.
108 108 assertTrue(fTargetClassName + " did not match .class file",
109 109 fTargetClassMatches);
110 110
111 111 fTargetClassSeen = false;
112 112 fTargetClassMatches = false;
113 113
114 114 fInst.retransformClasses(target);
115 115
116 116 assertTrue(fTargetClassName + " was not seen by transform()",
117 117 fTargetClassSeen);
118 118
119 119 // The HotSpot VM doesn't currently preserve the LocalVariable
120 120 // Table (LVT) attribute so the class file bytes seen by the
121 121 // retransformClasses() call will not match the class file bytes
122 122 // seen at initial class load time.
123 123 assertTrue(fTargetClassName + " did not match .class file",
124 124 fTargetClassMatches);
125 125 }
126 126
127 127 public class MyObserver implements ClassFileTransformer {
128 128 public MyObserver() {
129 129 }
130 130
131 131 public String toString() {
132 132 return MyObserver.this.getClass().getName();
133 133 }
134 134
135 135 private void saveMismatchedBytes(byte[] classfileBuffer) {
136 136 try {
137 137 FileOutputStream fos = null;
138 138 // This file will get created in the test execution
139 139 // directory so there is no conflict with the file
140 140 // in the test classes directory.
141 141 String resourceName = fTargetClassName + ".class";
142 142 fos = new FileOutputStream(resourceName);
143 143 fos.write(classfileBuffer);
144 144 fos.close();
145 145 } catch (IOException ex) {
146 146 }
147 147 }
148 148
149 149 public byte[]
150 150 transform(
151 151 ClassLoader loader,
152 152 String className,
153 153 Class<?> classBeingRedefined,
154 154 ProtectionDomain protectionDomain,
155 155 byte[] classfileBuffer) {
156 156
157 157 System.out.println(this + ".transform() sees '" + className
158 158 + "' of " + classfileBuffer.length + " bytes.");
159 159 if (className.equals(fTargetClassName)) {
160 160 fTargetClassSeen = true;
161 161
162 162 if (classfileBuffer.length != fTargetClassBytes.length) {
163 163 System.out.println("Warning: " + fTargetClassName
164 164 + " lengths do not match.");
165 165 fTargetClassMatches = false;
166 166 saveMismatchedBytes(classfileBuffer);
167 167 return null;
168 168 } else {
169 169 System.out.println("Info: " + fTargetClassName
170 170 + " lengths match.");
171 171 }
172 172
173 173 for (int i = 0; i < classfileBuffer.length; i++) {
174 174 if (classfileBuffer[i] != fTargetClassBytes[i]) {
175 175 System.out.println("Warning: " + fTargetClassName
176 176 + "[" + i + "]: '" + classfileBuffer[i]
177 177 + "' != '" + fTargetClassBytes[i] + "'");
178 178 fTargetClassMatches = false;
179 179 saveMismatchedBytes(classfileBuffer);
180 180 return null;
181 181 }
182 182 }
183 183
184 184 fTargetClassMatches = true;
185 185 System.out.println("Info: verified '" + fTargetClassName
186 186 + ".class' matches 'classfileBuffer'.");
187 187 }
188 188
189 189 return null;
190 190 }
191 191 }
192 192 }
↓ open down ↓ |
79 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX