I wrote a java transformer which is installed from a java agent premain. This
transformer just takes the input class bytecode and pass it through a
do-nothing class visitor which is implemented as follows:
class MyClassVisitor extends ClassAdapter {
public MyClassVisitor(ClassVisitor cv) {
super(cv);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
return new MethodAdapter(super.visitMethod(access, name, desc,
signature, exceptions));
}
}
The writer is created with COMPUTE_FRAMES flag. My application freezes during
startup. If I remove the COMPUTE_FRAMES flag, then everything goes fine. If I
remove the MethodAdapter from visitMethod, so that it's implemented as:
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
return super.visitMethod(access, name, desc,
signature, exceptions);
}
everything goes fine too. This is strange, because the adapter is simply a
delegator. Here follows the complete transformer code, I don't know if you will
be able to reproduce the problem because it may depend on the specific classes
that are loaded during jvm bootup.
public class InstrumentationTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className,
Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws IllegalClassFormatException {
ClassReader reader = new ClassReader(classfileBuffer);
ClassWriter writer = new ClassWriter(reader,
ClassWriter.COMPUTE_FRAMES);
ClassVisitor visitor = new MyClassVisitor(writer);
reader.accept(visitor, 0);
return writer.toByteArray();
}
private static class MyClassVisitor extends ClassAdapter {
public MyClassVisitor(ClassVisitor cv) {
super(cv);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
return new MethodAdapter(super.visitMethod(access, name, desc,
signature, exceptions));
}
}
}