/*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
*
*
* @bug 6439234 6446941
*
* Test attach used in concert with transformers and redefineClasses.
*
* 6439234 java.lang.instrument: 8 JCK JPLIS tests fail when running in Live phase (no transform events)
* 6446941 java.lang.instrument: multiple agent attach fails (first agent chooses capabilities)
*/
import java.net.Socket;
import java.net.InetSocketAddress;
import java.io.IOException;
import java.util.Arrays;
import java.security.ProtectionDomain;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.ClassDefinition;
public class RedefineAgent implements ClassFileTransformer {
static byte[] classfilebytes;
static final String targetName = "java.math.BigInteger";
static final String targetNameSlashes = "java/math/BigInteger";
static boolean gotRedefineTransform = false;
// test transform and capture class bytes for redefine
public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer) {
if (className.equals(targetNameSlashes)) {
if (classBeingRedefined == null) {
System.out.println("Got bytes for: " + className);
classfilebytes = Arrays.copyOf(classfileBuffer, classfileBuffer.length);
} else {
gotRedefineTransform = true;
}
}
return null;
}
// test transform and redefine for an attached agent
public static void testRedefine(Instrumentation inst) throws Exception {
Class[] classes = inst.getAllLoadedClasses();
for (Class k : classes) {
if (k.getName().equals(targetName)) {
throw new Exception("RedefineAgent Test error: class " + targetName + " has already been loaded.");
}
}
inst.addTransformer(new RedefineAgent());
ClassLoader.getSystemClassLoader().loadClass(targetName);
classes = inst.getAllLoadedClasses();
Class targetClass = null;
for (Class k : classes) {
if (k.getName().equals(targetName)) {
targetClass = k;
break;
}
}
if (targetClass == null) {
throw new Exception("RedefineAgent Test error: class " + targetName + " not loaded.");
}
if (classfilebytes == null) {
throw new Exception("RedefineAgent Error(6439234): no transform call for class " + targetName);
}
ClassDefinition cd = new ClassDefinition(targetClass, classfilebytes);
inst.redefineClasses(cd);
System.out.println("RedefineAgent did redefine.");
if (gotRedefineTransform) {
System.out.println("RedefineAgent got redefine transform.");
} else {
throw new Exception("RedefineAgent Error(6439234): no transform call for redefine " + targetName);
}
}
public static void agentmain(String args, Instrumentation inst) throws Exception {
System.out.println("RedefineAgent running...");
System.out.println("RedefineAgent redefine supported: " + inst.isRedefineClassesSupported());
int port = Integer.parseInt(args);
System.out.println("RedefineAgent connecting back to Tool....");
Socket s = new Socket();
s.connect( new InetSocketAddress(port) );
System.out.println("RedefineAgent connected to Tool.");
testRedefine(inst);
s.close();
}
}