//: net/mindview/atunit/AtUnitRemover.java // Displays @Unit annotations in compiled class files. If // first argument is "-r", @Unit annotations are removed. // {Args: ..} // {Requires: javassist.bytecode.ClassFile; // You must install the Javassist library from // www.javassist.org } package net.mindview.atunit; import javassist.*; import javassist.bytecode.*; import javassist.bytecode.annotation.*; import java.io.*; import net.mindview.util.*; import static net.mindview.util.Print.*; public class AtUnitRemover implements ProcessFiles.Strategy { private static boolean remove = false; public static void main(String[] args) throws Exception { if(args.length > 0 && args[0].equals("-r")) { remove = true; String[] nargs = new String[args.length - 1]; System.arraycopy(args, 1, nargs, 0, nargs.length); args = nargs; } new ProcessFiles( new AtUnitRemover(), "class").start(args); } @Override public void process(File cFile) { boolean modified = false; try { String cName = ClassNameFinder.thisClass( BinaryFile.read(cFile)); if(!cName.contains(".")) return; // Ignore unpackaged classes ClassPool cPool = ClassPool.getDefault(); CtClass ctClass = cPool.get(cName); for(CtMethod method : ctClass.getDeclaredMethods()) { MethodInfo mi = method.getMethodInfo(); AnnotationsAttribute attr = (AnnotationsAttribute) mi.getAttribute(AnnotationsAttribute.visibleTag); if(attr == null) continue; for(Annotation ann : attr.getAnnotations()) { if(ann.getTypeName() .startsWith("net.mindview.atunit")) { print(ctClass.getName() + " Method: " + mi.getName() + " " + ann); if(remove) { ctClass.removeMethod(method); modified = true; } } } } // Fields are not removed in this version (see text). if(modified) ctClass.toBytecode(new DataOutputStream( new FileOutputStream(cFile))); ctClass.detach(); } catch(Exception e) { throw new RuntimeException(e); } } } ///:~