1 package org.hansel; 2 3 import java.io.ByteArrayInputStream ; 4 import java.io.FileOutputStream ; 5 import java.lang.instrument.ClassDefinition ; 6 import java.lang.instrument.ClassFileTransformer ; 7 import java.lang.instrument.IllegalClassFormatException ; 8 import java.lang.instrument.Instrumentation ; 9 import java.lang.instrument.UnmodifiableClassException ; 10 import java.security.ProtectionDomain ; 11 import java.util.List ; 12 import java.util.Set ; 13 import java.util.Vector ; 14 15 import org.objectweb.asm.ClassReader; 16 import org.objectweb.asm.ClassWriter; 17 import org.objectweb.asm.tree.ClassNode; 18 19 public class Transformer implements ClassFileTransformer { 20 private Set <String > classNames; 21 private List <ClassEntry> redefinedClasses = new Vector <ClassEntry>(); 22 23 public Transformer(Set <String > classNames) { 24 this.classNames = classNames; 25 } 26 27 public byte[] transform(ClassLoader loader, 28 String className, 29 Class <?> classBeingRedefined, 30 ProtectionDomain protectionDomain, 31 byte[] classfileBuffer) 32 throws IllegalClassFormatException { 33 34 if (!classNames.contains(className.replace('/', '.'))) { 35 return null; 36 } 37 38 try { 39 ClassReader cr = new ClassReader(new ByteArrayInputStream (classfileBuffer)); 40 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES + ClassWriter.COMPUTE_MAXS); 41 42 ClassNode cn = new ClassNode(); 43 cr.accept(cn, 0); 44 45 TransformingAdapter ta = new TransformingAdapter(cw, cn, loader); 46 47 cn.accept(ta); 48 49 redefinedClasses.add(new ClassEntry(className, loader, 51 classfileBuffer)); 52 byte[] result = cw.toByteArray(); 53 54 if (cn.name.endsWith("Example")) { 55 FileOutputStream out = new FileOutputStream ("test.class"); 56 out.write(result); 57 out.close(); 58 } 59 61 return result; 62 } catch (Throwable e) { 63 e.printStackTrace(); 64 throw new IllegalClassFormatException (e.getMessage()); 65 } 66 } 67 68 public void undo(Instrumentation instrumentation) 69 throws ClassNotFoundException , UnmodifiableClassException { 70 71 ClassDefinition [] oldClasses = 72 new ClassDefinition [redefinedClasses.size()]; 73 74 for (int i=0; i<oldClasses.length; i++) { 75 oldClasses[i] = 76 redefinedClasses.get(i).toClassDefinition(); 77 } 78 79 instrumentation.redefineClasses(oldClasses); 80 } 81 82 private static class ClassEntry { 83 private ClassLoader cl; 84 private byte[] classBuffer; 85 private String classname; 86 87 public ClassEntry(String classname, ClassLoader cl, 88 byte[] classBuffer) { 89 this.cl = cl; 90 this.classname = classname; 91 this.classBuffer = classBuffer; 92 93 101 } 102 103 public ClassDefinition toClassDefinition() throws ClassNotFoundException { 104 return new ClassDefinition (cl.loadClass(classname.replace('/', '.')), 105 classBuffer); 106 } 107 } 108 } 109 | Popular Tags |