8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.instrument;
27
28 import java.lang.instrument.Instrumentation;
29 import java.lang.instrument.ClassFileTransformer;
30 import java.security.ProtectionDomain;
31
32 /*
33 * Copyright 2003 Wily Technology, Inc.
34 */
35
36 /**
37 * Support class for the InstrumentationImpl. Manages the list of registered transformers.
38 * Keeps everything in the right order, deals with sync of the list,
39 * and actually does the calling of the transformers.
40 */
41 public class TransformerManager
42 {
43 private class TransformerInfo {
44 final ClassFileTransformer mTransformer;
45 String mPrefix;
46
47 TransformerInfo(ClassFileTransformer transformer) {
48 mTransformer = transformer;
158
159 // This function doesn't actually snapshot anything, but should be
160 // used to set a local variable, which will snapshot the transformer
161 // list because of the copying semantics of mTransformerList (see
162 // the comment for mTransformerList).
163 private TransformerInfo[]
164 getSnapshotTransformerList() {
165 return mTransformerList;
166 }
167
168 public byte[]
169 transform( Module module,
170 ClassLoader loader,
171 String classname,
172 Class<?> classBeingRedefined,
173 ProtectionDomain protectionDomain,
174 byte[] classfileBuffer) {
175 boolean someoneTouchedTheBytecode = false;
176
177 TransformerInfo[] transformerList = getSnapshotTransformerList();
178
179 byte[] bufferToUse = classfileBuffer;
180
181 // order matters, gotta run 'em in the order they were added
182 for ( int x = 0; x < transformerList.length; x++ ) {
183 TransformerInfo transformerInfo = transformerList[x];
184 ClassFileTransformer transformer = transformerInfo.transformer();
185 byte[] transformedBytes = null;
186
187 try {
188 transformedBytes = transformer.transform( module,
189 loader,
190 classname,
191 classBeingRedefined,
192 protectionDomain,
193 bufferToUse);
194 }
195 catch (Throwable t) {
196 // don't let any one transformer mess it up for the others.
197 // This is where we need to put some logging. What should go here? FIXME
198 }
199
200 if ( transformedBytes != null ) {
201 someoneTouchedTheBytecode = true;
202 bufferToUse = transformedBytes;
203 }
204 }
205
206 // if someone modified it, return the modified buffer.
207 // otherwise return null to mean "no transforms occurred"
208 byte [] result;
209 if ( someoneTouchedTheBytecode ) {
210 result = bufferToUse;
211 }
212 else {
213 result = null;
214 }
215
216 return result;
217 }
218
219
220 int
221 getTransformerCount() {
222 TransformerInfo[] transformerList = getSnapshotTransformerList();
223 return transformerList.length;
224 }
225
226 boolean
227 setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) {
228 TransformerInfo[] transformerList = getSnapshotTransformerList();
229
230 for ( int x = 0; x < transformerList.length; x++ ) {
231 TransformerInfo transformerInfo = transformerList[x];
232 ClassFileTransformer aTransformer = transformerInfo.transformer();
233
234 if ( aTransformer == transformer ) {
235 transformerInfo.setPrefix(prefix);
236 return true;
237 }
238 }
239 return false;
|
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.instrument;
27
28 import java.lang.instrument.ClassFileTransformer;
29 import java.security.ProtectionDomain;
30
31 /*
32 * Copyright 2003 Wily Technology, Inc.
33 */
34
35 /**
36 * Support class for the InstrumentationImpl. Manages the list of registered transformers.
37 * Keeps everything in the right order, deals with sync of the list,
38 * and actually does the calling of the transformers.
39 */
40 public class TransformerManager
41 {
42 private class TransformerInfo {
43 final ClassFileTransformer mTransformer;
44 String mPrefix;
45
46 TransformerInfo(ClassFileTransformer transformer) {
47 mTransformer = transformer;
157
158 // This function doesn't actually snapshot anything, but should be
159 // used to set a local variable, which will snapshot the transformer
160 // list because of the copying semantics of mTransformerList (see
161 // the comment for mTransformerList).
162 private TransformerInfo[]
163 getSnapshotTransformerList() {
164 return mTransformerList;
165 }
166
167 public byte[]
168 transform( Module module,
169 ClassLoader loader,
170 String classname,
171 Class<?> classBeingRedefined,
172 ProtectionDomain protectionDomain,
173 byte[] classfileBuffer) {
174 boolean someoneTouchedTheBytecode = false;
175
176 TransformerInfo[] transformerList = getSnapshotTransformerList();
177 byte[] bufferToUse = classfileBuffer;
178
179 try (CloseableClassDefiner classDefiner = new CloseableClassDefiner(classname, loader, protectionDomain)) {
180 // order matters, gotta run 'em in the order they were added
181 for (int x = 0; x < transformerList.length; x++) {
182 TransformerInfo transformerInfo = transformerList[x];
183 ClassFileTransformer transformer = transformerInfo.transformer();
184 byte[] transformedBytes = null;
185 try {
186 transformedBytes = transformer.transform(classDefiner,
187 module,
188 loader,
189 classname,
190 classBeingRedefined,
191 protectionDomain,
192 bufferToUse);
193 } catch (Throwable t) {
194 // don't let any one transformer mess it up for the others.
195 // This is where we need to put some logging. What should go here? FIXME
196 }
197
198 if (transformedBytes != null) {
199 someoneTouchedTheBytecode = true;
200 bufferToUse = transformedBytes;
201 }
202 }
203 }
204
205
206 // if someone modified it, return the modified buffer.
207 // otherwise return null to mean "no transforms occurred"
208 byte [] result;
209 if ( someoneTouchedTheBytecode ) {
210 result = bufferToUse;
211 }
212 else {
213 result = null;
214 }
215
216 return result;
217 }
218
219 int
220 getTransformerCount() {
221 TransformerInfo[] transformerList = getSnapshotTransformerList();
222 return transformerList.length;
223 }
224
225 boolean
226 setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) {
227 TransformerInfo[] transformerList = getSnapshotTransformerList();
228
229 for ( int x = 0; x < transformerList.length; x++ ) {
230 TransformerInfo transformerInfo = transformerList[x];
231 ClassFileTransformer aTransformer = transformerInfo.transformer();
232
233 if ( aTransformer == transformer ) {
234 transformerInfo.setPrefix(prefix);
235 return true;
236 }
237 }
238 return false;
|