1 30 import org.objectweb.asm.FieldVisitor; 31 import org.objectweb.asm.ClassAdapter; 32 import org.objectweb.asm.ClassReader; 33 import org.objectweb.asm.ClassVisitor; 34 import org.objectweb.asm.ClassWriter; 35 import org.objectweb.asm.MethodAdapter; 36 import org.objectweb.asm.MethodVisitor; 37 import org.objectweb.asm.Opcodes; 38 import org.objectweb.asm.Type; 39 40 import java.io.FileOutputStream ; 41 import java.io.InputStream ; 42 import java.lang.reflect.Method ; 43 44 47 public class Adapt extends ClassLoader { 48 49 protected synchronized Class loadClass( 50 final String name, 51 final boolean resolve) throws ClassNotFoundException 52 { 53 if (name.startsWith("java.")) { 54 System.err.println("Adapt: loading class '" + name 55 + "' without on the fly adaptation"); 56 return super.loadClass(name, resolve); 57 } else { 58 System.err.println("Adapt: loading class '" + name 59 + "' with on the fly adaptation"); 60 } 61 62 String resource = name.replace('.', '/') + ".class"; 64 InputStream is = getResourceAsStream(resource); 65 byte[] b; 66 67 try { 69 ClassReader cr = new ClassReader(is); 70 ClassWriter cw = new ClassWriter(false); 71 ClassVisitor cv = new TraceFieldClassAdapter(cw); 72 cr.accept(cv, false); 73 b = cw.toByteArray(); 74 } catch (Exception e) { 75 throw new ClassNotFoundException (name, e); 76 } 77 78 try { 80 FileOutputStream fos = new FileOutputStream (resource + ".adapted"); 81 fos.write(b); 82 fos.close(); 83 } catch (Exception e) { 84 } 85 86 return defineClass(name, b, 0, b.length); 88 } 89 90 public static void main(final String args[]) throws Exception { 91 ClassLoader loader = new Adapt(); 93 Class c = loader.loadClass(args[0]); 94 Method m = c.getMethod("main", new Class [] { String [].class }); 97 String [] applicationArgs = new String [args.length - 1]; 98 System.arraycopy(args, 1, applicationArgs, 0, applicationArgs.length); 99 m.invoke(null, new Object [] { applicationArgs }); 100 } 101 } 102 103 class TraceFieldClassAdapter extends ClassAdapter implements Opcodes { 104 105 private String owner; 106 107 public TraceFieldClassAdapter(final ClassVisitor cv) { 108 super(cv); 109 } 110 111 public void visit( 112 final int version, 113 final int access, 114 final String name, 115 final String signature, 116 final String superName, 117 final String [] interfaces) 118 { 119 owner = name; 120 super.visit(version, access, name, signature, superName, interfaces); 121 } 122 123 public FieldVisitor visitField( 124 final int access, 125 final String name, 126 final String desc, 127 final String signature, 128 final Object value) 129 { 130 FieldVisitor fv = super.visitField(access, name, desc, signature, value); 131 if ((access & ACC_STATIC) == 0) { 132 Type t = Type.getType(desc); 133 int size = t.getSize(); 134 135 String gDesc = "()" + desc; 137 MethodVisitor gv = cv.visitMethod(ACC_PRIVATE, 138 "_get" + name, 139 gDesc, 140 null, 141 null); 142 gv.visitFieldInsn(GETSTATIC, 143 "java/lang/System", 144 "err", 145 "Ljava/io/PrintStream;"); 146 gv.visitLdcInsn("_get" + name + " called"); 147 gv.visitMethodInsn(INVOKEVIRTUAL, 148 "java/io/PrintStream", 149 "println", 150 "(Ljava/lang/String;)V"); 151 gv.visitVarInsn(ALOAD, 0); 152 gv.visitFieldInsn(GETFIELD, owner, name, desc); 153 gv.visitInsn(t.getOpcode(IRETURN)); 154 gv.visitMaxs(1 + size, 1); 155 gv.visitEnd(); 156 157 String sDesc = "(" + desc + ")V"; 159 MethodVisitor sv = cv.visitMethod(ACC_PRIVATE, 160 "_set" + name, 161 sDesc, 162 null, 163 null); 164 sv.visitFieldInsn(GETSTATIC, 165 "java/lang/System", 166 "err", 167 "Ljava/io/PrintStream;"); 168 sv.visitLdcInsn("_set" + name + " called"); 169 sv.visitMethodInsn(INVOKEVIRTUAL, 170 "java/io/PrintStream", 171 "println", 172 "(Ljava/lang/String;)V"); 173 sv.visitVarInsn(ALOAD, 0); 174 sv.visitVarInsn(t.getOpcode(ILOAD), 1); 175 sv.visitFieldInsn(PUTFIELD, owner, name, desc); 176 sv.visitInsn(RETURN); 177 sv.visitMaxs(1 + size, 1 + size); 178 sv.visitEnd(); 179 } 180 return fv; 181 } 182 183 public MethodVisitor visitMethod( 184 final int access, 185 final String name, 186 final String desc, 187 final String signature, 188 final String [] exceptions) 189 { 190 MethodVisitor mv = cv.visitMethod(access, 191 name, 192 desc, 193 signature, 194 exceptions); 195 return mv == null ? null : new TraceFieldCodeAdapter(mv, owner); 196 } 197 } 198 199 class TraceFieldCodeAdapter extends MethodAdapter implements Opcodes { 200 201 private String owner; 202 203 public TraceFieldCodeAdapter(final MethodVisitor mv, final String owner) { 204 super(mv); 205 this.owner = owner; 206 } 207 208 public void visitFieldInsn( 209 final int opcode, 210 final String owner, 211 final String name, 212 final String desc) 213 { 214 if (owner.equals(this.owner)) { 215 if (opcode == GETFIELD) { 216 String gDesc = "()" + desc; 218 visitMethodInsn(INVOKESPECIAL, owner, "_get" + name, gDesc); 219 return; 220 } else if (opcode == PUTFIELD) { 221 String sDesc = "(" + desc + ")V"; 223 visitMethodInsn(INVOKESPECIAL, owner, "_set" + name, sDesc); 224 return; 225 } 226 } 227 super.visitFieldInsn(opcode, owner, name, desc); 228 } 229 } 230 | Popular Tags |