1 19 20 package org.netbeans.perftest; 21 22 import java.io.File ; 23 import java.util.Enumeration ; 24 import java.util.HashSet ; 25 import java.util.Set ; 26 import java.util.jar.JarEntry ; 27 import java.util.jar.JarFile ; 28 import junit.framework.TestCase; 29 import junit.framework.*; 30 import com.sun.org.apache.bcel.internal.classfile.ClassParser; 31 import com.sun.org.apache.bcel.internal.classfile.DescendingVisitor; 32 import com.sun.org.apache.bcel.internal.classfile.EmptyVisitor; 33 import com.sun.org.apache.bcel.internal.classfile.Field; 34 import com.sun.org.apache.bcel.internal.classfile.JavaClass; 35 import com.sun.org.apache.bcel.internal.classfile.LineNumberTable; 36 import com.sun.org.apache.bcel.internal.classfile.LocalVariableTable; 37 import com.sun.org.apache.bcel.internal.classfile.Method; 38 import com.sun.org.apache.bcel.internal.generic.Type; 39 import java.lang.reflect.Constructor ; 40 import java.util.TreeSet ; 41 import java.util.logging.Level ; 42 import java.util.logging.Logger ; 43 import org.netbeans.*; 44 import org.netbeans.junit.NbTestCase; 45 import org.netbeans.junit.NbTestSuite; 46 import org.openide.loaders.DataLoader; 47 import org.openide.loaders.DataLoaderPool; 48 49 53 public class BytecodeTest extends NbTestCase { 54 55 private Logger LOG; 56 57 public BytecodeTest(String testName) { 58 super(testName); 59 } 60 61 public static Test suite() { 62 TestSuite suite = new NbTestSuite(BytecodeTest.class); 63 64 return suite; 65 } 66 67 @Override 68 protected Level logLevel() { 69 return Level.INFO; 70 } 71 72 protected void setUp() throws Exception { 73 LOG = Logger.getLogger("TEST-" + getName()); 74 75 super.setUp(); 76 } 77 78 83 public void testBytecode() throws Exception { 84 JavaClass clz = 85 new ClassParser(Main.class.getResourceAsStream("Main.class"), "Main.class").parse(); 86 assertNotNull("classfile of Main parsed", clz); 87 88 Set <Violation> violations = new HashSet <Violation>(); 89 MyVisitor v = new MyVisitor(); 90 new DescendingVisitor(clz,v).visit(); 91 if (v.foundLocalVarTable()) { 92 violations.add(new Violation(Main.class.getName(), "startup classpath", "local var table found")); 93 } 94 for (File f: org.netbeans.core.startup.Main.getModuleSystem().getModuleJars()) { 95 if (!f.getName().endsWith(".jar")) 96 continue; 97 98 if ("commons-logging-1.0.4.jar".equals(f.getName()) 101 || "servlet-2.2.jar".equals(f.getName()) 102 || "servlet2.5-jsp2.1-api.jar".equals(f.getName()) 103 || "jaxws-tools.jar".equals(f.getName()) 104 || "jaxws-rt.jar".equals(f.getName()) 105 || "jaxb-impl.jar".equals(f.getName()) 106 || "jaxb-xjc.jar".equals(f.getName()) 107 || "jaxb-api.jar".equals(f.getName()) 108 || "saaj-impl.jar".equals(f.getName()) 109 || "activation.jar".equals(f.getName()) 110 || "streambuffer.jar".equals(f.getName()) 111 || "sjsxp.jar".equals(f.getName()) 112 || "resolver-1_1_nb.jar".equals(f.getName()) 113 || "webserver.jar".equals(f.getName()) 114 || "swing-layout-1.0.1.jar".equals(f.getName()) 115 || "persistence-tool-support.jar".equals(f.getName()) 117 || "ini4j.jar".equals(f.getName()) 118 || "svnClientAdapter.jar".equals(f.getName()) 119 || "lucene-core-2.0.0.jar".equals(f.getName()) 120 || "javac-impl.jar".equals(f.getName()) 121 || "java-parser.jar".equals(f.getName())) 122 continue; 123 124 JarFile jar = new JarFile (f); 125 Enumeration <JarEntry > entries = jar.entries(); 126 JarEntry entry; 127 while (entries.hasMoreElements()) { 128 entry = entries.nextElement(); 129 if (entry.getName().endsWith(".class")) { 130 LOG.log(Level.FINE, "testing entry {0}", entry); 131 clz = new ClassParser(jar.getInputStream(entry), entry.getName()).parse(); 132 assertNotNull("classfile of "+entry.toString()+" parsed"); 133 134 v = new MyVisitor(); 135 new DescendingVisitor(clz,v).visit(); 136 if (v.foundLocalVarTable()) { 137 violations.add(new Violation(entry.toString(), jar.getName(), "local var table found")); 138 } 139 140 break; 141 } 142 } 143 } 144 if (!violations.isEmpty()) { 145 StringBuilder msg = new StringBuilder (); 146 msg.append("Some classes in IDE contain variable table information:\n"); 147 for (Violation viol: violations) { 148 msg.append(viol.entry).append(" in ").append(viol.jarFile).append('\n'); 149 } 150 fail(msg.toString()); 151 } 152 } 154 155 private static class Violation implements Comparable <Violation> { 156 String entry; 157 String jarFile; 158 String comment; 159 Violation(String entry, String jarFile, String comment) { 160 this.entry = entry; 161 this.jarFile = jarFile; 162 this.comment = comment; 163 } 164 165 public int compareTo(Violation v2) { 166 String second = v2.entry + v2.jarFile; 167 return (entry +jarFile).compareTo(second); 168 } 169 } 170 171 private static class MyVisitor extends EmptyVisitor { 172 private boolean localVarTable; 173 private boolean lineNumberTable; 174 175 public void visitLocalVariableTable(LocalVariableTable obj) { 176 localVarTable = true; 177 } 178 179 public boolean foundLocalVarTable() { 180 return localVarTable; 181 } 182 183 public void visitLineNumberTable(LineNumberTable obj) { 184 lineNumberTable = true; 185 } 186 187 public boolean foundLineNumberTable() { 188 return lineNumberTable; 189 } 190 191 } 192 193 private static class BIVisitor extends EmptyVisitor { 194 195 private static Type pdType = Type.getType("[Ljava/beans/PropertyDescriptor;"); 196 private static Type bdType = Type.getType("Ljava/beans/BeanDescriptor;"); 197 private static Type mdType = Type.getType("[Ljava/beans/MethodDescriptor;"); 198 private static Type edType = Type.getType("[Ljava/beans/EventSetDescriptor;"); 199 private boolean hasDescFields; 200 private boolean hasStaticMethods; 201 202 public void visitField(Field obj) { 203 if (obj.isStatic()) { 204 Type name = Type.getReturnType(obj.getSignature()); 206 if (pdType.equals(name) || 207 bdType.equals(name) || 208 mdType.equals(name) || 209 edType.equals(name)) { 210 hasDescFields = true; 211 } 212 } 213 } 214 215 public void visitMethod(Method obj) { 216 if (obj.isStatic()) { String name = obj.getName(); 218 if ("getBdescriptor".equals(name) || 219 "getMdescriptor".equals(name) || 220 "getEdescriptor".equals(name) || 221 "getPdescriptor".equals(name)) { 222 hasStaticMethods = true; 223 } 224 } 225 } 226 227 public boolean foundDescFields() { 228 return hasDescFields; 229 } 230 231 public boolean foundStaticMethods() { 232 return hasStaticMethods; 233 } 234 } 235 236 private static class StaticsVisitor extends EmptyVisitor { 237 238 private static Type imageType = Type.getType("Ljava/awt/Image;"); 239 private static Type image1Type = Type.getType("Ljavax/swing/ImageIcon;"); 240 private static Type image2Type = Type.getType("Ljavax/swing/Icon;"); 241 private static Type bType = Type.getType("Ljava/util/ResourceBundle;"); 242 private static Type b2Type = Type.getType("Lorg/openide/util/NbBundle;"); 243 private boolean hasStaticFields; 244 245 public void visitField(Field obj) { 246 if (obj.isStatic()) { 247 Type name = Type.getReturnType(obj.getSignature()); 249 if (imageType.equals(name) || 250 image1Type.equals(name) || 251 image2Type.equals(name) || 252 bType.equals(name) || 253 b2Type.equals(name)) { 254 hasStaticFields = true; 255 } 256 } 257 } 258 259 public boolean foundStaticFields() { 260 return hasStaticFields; 261 } 262 263 } 264 265 267 public void testBeanInfos() throws Exception { 268 JavaClass clz; 269 270 Set <Violation> violations = new TreeSet <Violation>(); 271 for (File f: org.netbeans.core.startup.Main.getModuleSystem().getModuleJars()) { 272 if (!f.getName().endsWith(".jar")) 273 continue; 274 275 JarFile jar = new JarFile (f); 276 Enumeration <JarEntry > entries = jar.entries(); 277 JarEntry entry; 278 while (entries.hasMoreElements()) { 279 entry = entries.nextElement(); 280 if (entry.getName().endsWith("BeanInfo.class")) { 281 LOG.log(Level.FINE, "testing entry {0}", entry); 282 clz = new ClassParser(jar.getInputStream(entry), entry.getName()).parse(); 283 assertNotNull("classfile of "+entry.toString()+" parsed"); 284 285 BIVisitor v = new BIVisitor(); 286 new DescendingVisitor(clz,v).visit(); 287 if (v.foundDescFields()) { 288 violations.add(new Violation(entry.toString(), jar.getName(), " found fields that should be avoided")); 289 } 290 if (v.foundStaticMethods()) { 291 violations.add(new Violation(entry.toString(), jar.getName(), " found methods that should be avoided")); 292 } 293 } 294 } 295 } 296 if (!violations.isEmpty()) { 297 StringBuilder msg = new StringBuilder (); 298 msg.append("Some BeanInfo classes should be more optimized:\n"); 299 for (Violation v: violations) { 300 msg.append(v.entry).append(" in ").append(v.jarFile).append(v.comment).append('\n'); 301 } 302 fail(msg.toString()); 303 } 304 } 305 307 public void testStaticRefs() throws Exception { 308 JavaClass clz; 309 310 312 Set <Violation> violations = new TreeSet <Violation>(); 313 for (File f: org.netbeans.core.startup.Main.getModuleSystem().getModuleJars()) { 314 if (!f.getName().endsWith(".jar")) 315 continue; 316 317 if (f.getName().endsWith("servlet-2.2.jar") 318 || f.getName().endsWith("servlet2.5-jsp2.1-api.jar") 319 || f.getName().endsWith("javac-impl.jar") 320 || f.getName().endsWith("jaxb-impl.jar") 321 || f.getName().endsWith("jaxb-xjc.jar") 322 || f.getName().endsWith("saaj-impl.jar") 323 || f.getName().endsWith("jh-2.0_04.jar") 324 || f.getName().endsWith("xerces-2.8.0.jar") 325 || f.getName().endsWith("svnClientAdapter.jar") 326 || f.getName().endsWith("persistence-tool-support.jar") || f.getName().endsWith("org-netbeans-modules-websvc-core.jar") || f.getName().endsWith("org-netbeans-modules-websvc-jaxrpc.jar") 329 || f.getName().endsWith("org-netbeans-modules-j2ee-sun-appsrv.jar") || f.getName().endsWith("org-netbeans-modules-j2ee-sun-appsrv81.jar") 331 || f.getName().endsWith("org-netbeans-modules-j2ee-ejbjarproject.jar") || f.getName().endsWith("org-netbeans-modules-j2ee-earproject.jar") 333 || f.getName().endsWith("org-netbeans-modules-j2ee-clientproject.jar") 334 || f.getName().endsWith("org-netbeans-modules-j2ee-blueprints.jar") 335 || f.getName().endsWith("org-netbeans-modules-j2ee-archive.jar") 336 || f.getName().endsWith("org-netbeans-modules-j2ee-ddloaders.jar") 337 || f.getName().endsWith("org-netbeans-modules-j2ee-dd.jar") 338 || f.getName().endsWith("org-netbeans-modules-j2ee-api-ejbmodule.jar") 339 || f.getName().endsWith("org-netbeans-modules-web-project.jar") || f.getName().endsWith("org-netbeans-modules-web-core-syntax.jar") 341 || f.getName().endsWith("org-netbeans-modules-java-source.jar") || f.getName().endsWith("org-netbeans-modules-java-project.jar") 343 || f.getName().endsWith("org-netbeans-modules-java-j2seproject.jar") 344 || f.getName().endsWith("org-netbeans-modules-java-platform.jar") 345 || f.getName().endsWith("org-netbeans-modules-j2ee-sun-ddui.jar")) { continue; 347 } 348 JarFile jar = new JarFile (f); 349 Enumeration <JarEntry > entries = jar.entries(); 350 JarEntry entry; 351 while (entries.hasMoreElements()) { 352 entry = entries.nextElement(); 353 if (entry.getName().endsWith(".class")) { 354 if ("org/openide/explorer/view/VisualizerNode.class".equals(entry.getName()) || "org/openide/awt/JInlineMenu.class".equals(entry.getName()) || "org/openide/awt/DynaMenuModel.class".equals(entry.getName()) || "org/netbeans/swing/tabcontrol/TabData.class".equals(entry.getName()) || "org/openide/explorer/propertysheet/PropertySheet.class".equals(entry.getName())) { continue; 360 } else if (entry.getName().startsWith("org/netbeans/modules/editor/java/JavaCompletionItem")) { continue; 362 } 363 364 LOG.log(Level.FINE, "testing entry {0}", entry); 365 clz = new ClassParser(jar.getInputStream(entry), entry.getName()).parse(); 366 assertNotNull("classfile of "+entry.toString()+" parsed"); 367 368 StaticsVisitor v = new StaticsVisitor(); 369 new DescendingVisitor(clz,v).visit(); 370 if (v.foundStaticFields()) { 371 violations.add(new Violation(entry.toString(), jar.getName(), " found static fields that should be avoided")); 372 } 373 } 374 } 375 } 376 if (!violations.isEmpty()) { 377 StringBuilder msg = new StringBuilder (); 378 msg.append("Some classes retain memory permanently:\n"); 379 for (Violation v: violations) { 380 msg.append(v.entry).append(" in ").append(v.jarFile).append(v.comment).append('\n'); 381 } 382 fail(msg.toString()); 383 } 384 } 385 386 389 public void testDataLoaders() throws Exception { 390 Enumeration <DataLoader> loaders = DataLoaderPool.getDefault().allLoaders(); 391 while (loaders.hasMoreElements()) { 392 DataLoader ldr = loaders.nextElement(); 393 try { 394 Constructor ctor = ldr.getClass().getDeclaredConstructor(Class .class); 396 assertNull(ldr.getClass().getName()+".<init>(String) is better are usualy enough", ctor); 397 } catch (NoSuchMethodException ex) { 398 } 400 } 401 } 402 } 403 | Popular Tags |