blob: e4280d538f0fe762d68ad7dec50d097d77d44045 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2006 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 *
26 *
27 * @bug 6439234 6446941
28 *
29 * Test attach used in concert with transformers and redefineClasses.
30 *
31 * 6439234 java.lang.instrument: 8 JCK JPLIS tests fail when running in Live phase (no transform events)
32 * 6446941 java.lang.instrument: multiple agent attach fails (first agent chooses capabilities)
33 */
34import java.net.Socket;
35import java.net.InetSocketAddress;
36import java.io.IOException;
37import java.util.Arrays;
38import java.security.ProtectionDomain;
39import java.lang.instrument.ClassFileTransformer;
40import java.lang.instrument.Instrumentation;
41import java.lang.instrument.ClassDefinition;
42
43public class RedefineAgent implements ClassFileTransformer {
44
45 static byte[] classfilebytes;
46 static final String targetName = "java.math.BigInteger";
47 static final String targetNameSlashes = "java/math/BigInteger";
48 static boolean gotRedefineTransform = false;
49
50 // test transform and capture class bytes for redefine
51 public byte[] transform(ClassLoader loader,
52 String className,
53 Class<?> classBeingRedefined,
54 ProtectionDomain protectionDomain,
55 byte[] classfileBuffer) {
56 if (className.equals(targetNameSlashes)) {
57 if (classBeingRedefined == null) {
58 System.out.println("Got bytes for: " + className);
59 classfilebytes = Arrays.copyOf(classfileBuffer, classfileBuffer.length);
60 } else {
61 gotRedefineTransform = true;
62 }
63 }
64 return null;
65 }
66
67 // test transform and redefine for an attached agent
68 public static void testRedefine(Instrumentation inst) throws Exception {
69 Class[] classes = inst.getAllLoadedClasses();
70 for (Class k : classes) {
71 if (k.getName().equals(targetName)) {
72 throw new Exception("RedefineAgent Test error: class " + targetName + " has already been loaded.");
73 }
74 }
75 inst.addTransformer(new RedefineAgent());
76 ClassLoader.getSystemClassLoader().loadClass(targetName);
77 classes = inst.getAllLoadedClasses();
78 Class targetClass = null;
79 for (Class k : classes) {
80 if (k.getName().equals(targetName)) {
81 targetClass = k;
82 break;
83 }
84 }
85 if (targetClass == null) {
86 throw new Exception("RedefineAgent Test error: class " + targetName + " not loaded.");
87 }
88 if (classfilebytes == null) {
89 throw new Exception("RedefineAgent Error(6439234): no transform call for class " + targetName);
90 }
91 ClassDefinition cd = new ClassDefinition(targetClass, classfilebytes);
92 inst.redefineClasses(cd);
93 System.out.println("RedefineAgent did redefine.");
94 if (gotRedefineTransform) {
95 System.out.println("RedefineAgent got redefine transform.");
96 } else {
97 throw new Exception("RedefineAgent Error(6439234): no transform call for redefine " + targetName);
98 }
99 }
100
101 public static void agentmain(String args, Instrumentation inst) throws Exception {
102 System.out.println("RedefineAgent running...");
103 System.out.println("RedefineAgent redefine supported: " + inst.isRedefineClassesSupported());
104 int port = Integer.parseInt(args);
105 System.out.println("RedefineAgent connecting back to Tool....");
106 Socket s = new Socket();
107 s.connect( new InetSocketAddress(port) );
108 System.out.println("RedefineAgent connected to Tool.");
109
110 testRedefine(inst);
111
112 s.close();
113 }
114
115}