blob: a88b75678ac97f43118a995b65e87b78b57c8408 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/**
25 * @test
26 * @bug 6274264 6274241 5070281
27 * @summary test retransformClasses
28 * @author Robert Field, Sun Microsystems
29 *
30 * @run shell MakeJAR2.sh RetransformAgent RetransformApp 'Can-Retransform-Classes: true'
31 * @run main/othervm -javaagent:RetransformAgent.jar RetransformApp
32 */
33
34import java.lang.instrument.*;
35import java.security.ProtectionDomain;
36import java.io.*;
37
38import ilib.*;
39
40class RetransformAgent {
41
42 static ClassFileTransformer t1, t2, t3, t4;
43 static Instrumentation inst;
44 static boolean succeeded = true;
45 static int markCount = 0;
46 static int[] markGolden = {30, 40, 20, 30, 40, 20, 30, 40, 20, 30, 40, 20,
47 11, 40, 20, 11, 40, 20, 11, 40, 20, 11, 40, 20};
48
49 static class Tr implements ClassFileTransformer {
50 final String trname;
51 final boolean onLoad;
52 final int loadIndex;
53 final boolean onRedef;
54 final int redefIndex;
55 final String cname;
56 final String nname;
57
58 Tr(String trname, boolean onLoad, int loadIndex, boolean onRedef, int redefIndex,
59 String cname, String nname) {
60 this.trname = trname;
61 this.onLoad = onLoad;
62 this.loadIndex = loadIndex;
63 this.onRedef = onRedef;
64 this.redefIndex = redefIndex;
65 this.cname = cname;
66 this.nname = nname;
67 }
68
69 public byte[] transform(ClassLoader loader,
70 String className,
71 Class<?> classBeingRedefined,
72 ProtectionDomain protectionDomain,
73 byte[] classfileBuffer) {
74 boolean redef = classBeingRedefined != null;
75 // System.err.println("hook " + trname + ": " + className +
76 // (redef? " REDEF" : " LOAD"));
77 if ((redef? onRedef : onLoad) && className != null && className.equals(cname)) {
78 Options opt = new Options();
79 opt.shouldInstrumentIndexed = true;
80 opt.shouldInstrumentCall = true;
81 opt.targetMethod = nname;
82 opt.fixedIndex = redef? redefIndex : loadIndex;
83 opt.trackerClassName = "RetransformAgent";
84 try {
85 byte[] newcf = Inject.instrumentation(opt, loader, className, classfileBuffer);
86 /*** debugging ...
87 String fname = trname + (redef?"_redef" : "");
88 write_buffer(fname + "_before.class", classfileBuffer);
89 write_buffer(fname + "_instr.class", newcf);
90 ***/
91 System.err.println(trname + ": " + className + " index: " + opt.fixedIndex +
92 (redef? " REDEF" : " LOAD") +
93 " len before: " + classfileBuffer.length +
94 " after: " + newcf.length);
95 return newcf;
96 } catch (Throwable ex) {
97 System.err.println("Injection failure: " + ex);
98 ex.printStackTrace();
99 }
100 }
101 return null;
102 }
103 }
104
105 static void write_buffer(String fname, byte[]buffer) {
106 try {
107 FileOutputStream outStream = new FileOutputStream(fname);
108 outStream.write(buffer, 0, buffer.length);
109 outStream.close();
110 } catch (Exception ex) {
111 System.err.println("EXCEPTION in write_buffer: " + ex);
112 }
113 }
114
115 public static void premain (String agentArgs, Instrumentation instArg) {
116 inst = instArg;
117 System.err.println("Premain");
118
119 t1 = new Tr("TR1", false, 10, true, 11, "RetransformApp", "foo");
120 inst.addTransformer(t1, true);
121 t2 = new Tr("TN2", true, 20, true, 21, "RetransformApp", "foo");
122 inst.addTransformer(t2, false);
123 t3 = new Tr("TR3", true, 30, true, 31, "RetransformApp", "foo");
124 inst.addTransformer(t3, true);
125 t4 = new Tr("TN4", true, 40, true, 41, "RetransformApp", "foo");
126 inst.addTransformer(t4, false);
127 }
128
129 public static void undo() {
130 inst.removeTransformer(t3);
131 try {
132 System.err.println("RETRANSFORM");
133 inst.retransformClasses(new RetransformApp().getClass());
134 } catch (Exception ex) {
135 System.err.println("EXCEPTION on undo: " + ex);
136 }
137 }
138
139 public static boolean succeeded() {
140 return succeeded && markCount == markGolden.length;
141 }
142
143 public static void callTracker(int mark) {
144 System.err.println("got mark " + mark);
145 if (markCount >= markGolden.length || mark != markGolden[markCount++]) {
146 succeeded = false;
147 }
148 }
149}