1 30 import java.lang.reflect.InvocationTargetException ; 31 import java.lang.reflect.Method ; 32 import java.util.ArrayList ; 33 import java.util.List ; 34 35 import org.objectweb.asm.AnnotationVisitor; 36 import org.objectweb.asm.ClassAdapter; 37 import org.objectweb.asm.ClassReader; 38 import org.objectweb.asm.ClassWriter; 39 import org.objectweb.asm.Label; 40 import org.objectweb.asm.MethodAdapter; 41 import org.objectweb.asm.MethodVisitor; 42 import org.objectweb.asm.Opcodes; 43 import org.objectweb.asm.Type; 44 45 public class Annotations { 46 47 public static void foo(final @NotNull 48 String arg) 49 { 50 System.out.println(arg); 51 } 52 53 public static void main(final String [] args) throws Exception { 54 System.out.println("Calling foo(null) results in a NullPointerException:"); 55 try { 56 foo(null); 57 } catch (Exception e) { 58 e.printStackTrace(System.out); 59 } 60 61 final String n = Annotations.class.getName(); 62 final ClassWriter cw = new ClassWriter(true); 63 ClassReader cr = new ClassReader(n); 64 cr.accept(new ClassAdapter(cw) { 65 66 public MethodVisitor visitMethod( 67 final int access, 68 final String name, 69 final String desc, 70 final String signature, 71 final String [] exceptions) 72 { 73 final Type[] args = Type.getArgumentTypes(desc); 74 MethodVisitor v = cv.visitMethod(access, 75 name, 76 desc, 77 signature, 78 exceptions); 79 return new MethodAdapter(v) { 80 81 private List params = new ArrayList (); 82 83 public AnnotationVisitor visitParameterAnnotation( 84 final int parameter, 85 final String desc, 86 final boolean visible) 87 { 88 AnnotationVisitor av; 89 av = mv.visitParameterAnnotation(parameter, 90 desc, 91 visible); 92 if (desc.equals("LNotNull;")) { 93 params.add(new Integer (parameter)); 94 } 95 return av; 96 } 97 98 public void visitCode() { 99 int var = ((access & Opcodes.ACC_STATIC) == 0) ? 1 : 0; 100 for (int p = 0; p < params.size(); ++p) { 101 int param = ((Integer ) params.get(p)).intValue(); 102 for (int i = 0; i < param; ++i) { 103 var += args[i].getSize(); 104 } 105 String c = "java/lang/IllegalArgumentException"; 106 String d = "(Ljava/lang/String;)V"; 107 Label end = new Label(); 108 mv.visitVarInsn(Opcodes.ALOAD, var); 109 mv.visitJumpInsn(Opcodes.IFNONNULL, end); 110 mv.visitTypeInsn(Opcodes.NEW, c); 111 mv.visitInsn(Opcodes.DUP); 112 mv.visitLdcInsn("Argument " + param 113 + " must not be null"); 114 mv.visitMethodInsn(Opcodes.INVOKESPECIAL, 115 c, 116 "<init>", 117 d); 118 mv.visitInsn(Opcodes.ATHROW); 119 mv.visitLabel(end); 120 } 121 } 122 }; 123 } 124 }, false); 125 126 Class c = new ClassLoader () { 127 public Class loadClass(final String name) 128 throws ClassNotFoundException  129 { 130 if (name.equals(n)) { 131 byte[] b = cw.toByteArray(); 132 return defineClass(name, b, 0, b.length); 133 } 134 return super.loadClass(name); 135 } 136 }.loadClass(n); 137 138 System.out.println(); 139 System.out.println("Calling foo(null) on the transformed class results in an IllegalArgumentException:"); 140 Method m = c.getMethod("foo", new Class [] { String .class }); 141 try { 142 m.invoke(null, new Object [] { null }); 143 } catch (InvocationTargetException e) { 144 e.getCause().printStackTrace(System.out); 145 } 146 } 147 } 148 | Popular Tags |