1 46 package org.codehaus.groovy.ant; 47 48 import java.io.File ; 49 import java.io.FileInputStream ; 50 import java.io.IOException ; 51 import java.util.List ; 52 53 import org.apache.tools.ant.BuildException; 54 import org.apache.tools.ant.taskdefs.MatchingTask; 55 import org.objectweb.asm.ClassReader; 56 import org.objectweb.asm.Label; 57 import org.objectweb.asm.util.CheckClassAdapter; 58 import org.objectweb.asm.util.TraceMethodVisitor; 59 import org.objectweb.asm.tree.AbstractInsnNode ; 60 import org.objectweb.asm.tree.ClassNode ; 61 import org.objectweb.asm.tree.MethodNode ; 62 import org.objectweb.asm.tree.analysis.Analyzer ; 63 import org.objectweb.asm.tree.analysis.Frame ; 64 import org.objectweb.asm.tree.analysis.SimpleVerifier ; 65 66 85 public class VerifyClass extends MatchingTask { 86 private String topDir=null; 87 private boolean verbose = false; 88 89 public VerifyClass() {} 90 91 public void execute() throws BuildException { 92 if (topDir==null) throw new BuildException("no dir attribute is set"); 93 File top = new File (topDir); 94 if (!top.exists()) throw new BuildException("the directory "+top+" does not exist"); 95 log ("top dir is "+top); 96 int fails = execute(top); 97 if (fails==0) { 98 log ("no bytecode problems found"); 99 } else { 100 log ("found "+fails+" failing classes"); 101 } 102 } 103 104 public void setDir(String dir) throws BuildException { 105 topDir = dir; 106 } 107 108 public void setVerbose(boolean v) { 109 verbose = v; 110 } 111 112 private int execute(File dir) { 113 int fails = 0; 114 File [] files = dir.listFiles(); 115 for (int i = 0; i < files.length; i++) { 116 File f =files[i]; 117 if (f.isDirectory()) { 118 fails += execute(f); 119 } else if (f.getName().endsWith(".class")) { 120 try { 121 boolean ok = readClass(f.getCanonicalPath()); 122 if (!ok) fails++; 123 } catch (IOException ioe) { 124 log(ioe.getMessage()); 125 throw new BuildException(ioe); 126 } 127 } 128 } 129 return fails; 130 } 131 132 private boolean readClass(String clazz) throws IOException { 133 ClassReader cr = new ClassReader(new FileInputStream (clazz)); 134 ClassNode ca = new ClassNode ( ) 135 { 136 public void visitEnd () { 137 } 139 } ; 140 cr.accept(new CheckClassAdapter(ca), true); 141 boolean failed=false; 142 143 List methods = ca.methods; 144 for (int i = 0; i < methods.size(); ++i) { 145 MethodNode method = (MethodNode)methods.get(i); 146 if (method.instructions.size() > 0) { 147 Analyzer a = new Analyzer(new SimpleVerifier()); 148 try { 149 a.analyze(ca.name, method); 150 continue; 151 } catch (Exception e) { 152 e.printStackTrace(); 153 } 154 final Frame[] frames = a.getFrames(); 155 156 if (!failed) { 157 failed=true; 158 log("verifying of class "+clazz+" failed"); 159 } 160 if (verbose) log(method.name + method.desc); 161 TraceMethodVisitor cv = new TraceMethodVisitor(null) { 162 public void visitMaxs (int maxStack, int maxLocals) { 163 StringBuffer buffer = new StringBuffer (); 164 for (int i = 0; i < text.size(); ++i) { 165 String s = frames[i] == null ? "null" : frames[i].toString(); 166 while (s.length() < maxStack+maxLocals+1) { 167 s += " "; 168 } 169 buffer.append(Integer.toString(i + 100000).substring(1)); 170 buffer.append(" "); 171 buffer.append(s); 172 buffer.append(" : "); 173 buffer.append(text.get(i)); 174 } 175 if (verbose) log(buffer.toString()); 176 } 177 }; 178 for (int j = 0; j < method.instructions.size(); ++j) { 179 Object insn = method.instructions.get(j); 180 if (insn instanceof AbstractInsnNode) { 181 ((AbstractInsnNode)insn).accept(cv); 182 } else { 183 cv.visitLabel((Label)insn); 184 } 185 } 186 cv.visitMaxs(method.maxStack, method.maxLocals); 187 } 188 } 189 return !failed; 190 } 191 192 } 193 | Popular Tags |