KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > perftest > BytecodeTest


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.perftest;
21
22 import java.io.File JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.HashSet JavaDoc;
25 import java.util.Set JavaDoc;
26 import java.util.jar.JarEntry JavaDoc;
27 import java.util.jar.JarFile JavaDoc;
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 JavaDoc;
40 import java.util.TreeSet JavaDoc;
41 import java.util.logging.Level JavaDoc;
42 import java.util.logging.Logger JavaDoc;
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 /**
50  *
51  * @author radim
52  */

53 public class BytecodeTest extends NbTestCase {
54     
55     private Logger JavaDoc LOG;
56
57     public BytecodeTest(String JavaDoc 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 JavaDoc
68     protected Level JavaDoc logLevel() {
69         return Level.INFO;
70     }
71
72     protected void setUp() throws Exception JavaDoc {
73         LOG = Logger.getLogger("TEST-" + getName());
74         
75         super.setUp();
76     }
77
78     /** Verification that classfiles built in production build do not contain
79      * variable information to reduce their size and improve performance.
80      * Line table and source info are OK.
81      * Likely to fail for custom CVS unless they used -Dbuild.compiler.debuglevel=source,lines
82      */

83     public void testBytecode() throws Exception JavaDoc {
84         JavaClass clz =
85                 new ClassParser(Main.class.getResourceAsStream("Main.class"), "Main.class").parse();
86         assertNotNull("classfile of Main parsed", clz);
87         
88         Set JavaDoc<Violation> violations = new HashSet JavaDoc<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 JavaDoc f: org.netbeans.core.startup.Main.getModuleSystem().getModuleJars()) {
95             if (!f.getName().endsWith(".jar"))
96                 continue;
97             
98             // list of 3rd party libs
99
// perhaps we can strip this debug info from these
100
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 // || "jmi.jar".equals(f.getName())
116
|| "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 JavaDoc jar = new JarFile JavaDoc(f);
125             Enumeration JavaDoc<JarEntry JavaDoc> entries = jar.entries();
126             JarEntry JavaDoc 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 JavaDoc msg = new StringBuilder JavaDoc();
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         // assertTrue (entry.toString()+" should have line number table", v.foundLineNumberTable());
153
}
154     
155     private static class Violation implements Comparable JavaDoc<Violation> {
156         String JavaDoc entry;
157         String JavaDoc jarFile;
158         String JavaDoc comment;
159         Violation(String JavaDoc entry, String JavaDoc jarFile, String JavaDoc comment) {
160             this.entry = entry;
161             this.jarFile = jarFile;
162             this.comment = comment;
163         }
164     
165         public int compareTo(Violation v2) {
166             String JavaDoc 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 // System.out.println("signature "+obj.getSignature());
205
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()) { // && obj.getArgumentTypes().length == 0) {
217
String JavaDoc 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 // System.out.println("signature "+obj.getSignature());
248
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     /** Scan of BeanInfo classes to check if they held descriptors statically
266      */

267     public void testBeanInfos() throws Exception JavaDoc {
268         JavaClass clz;
269         
270         Set JavaDoc<Violation> violations = new TreeSet JavaDoc<Violation>();
271         for (File JavaDoc f: org.netbeans.core.startup.Main.getModuleSystem().getModuleJars()) {
272             if (!f.getName().endsWith(".jar"))
273                 continue;
274             
275             JarFile JavaDoc jar = new JarFile JavaDoc(f);
276             Enumeration JavaDoc<JarEntry JavaDoc> entries = jar.entries();
277             JarEntry JavaDoc 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 JavaDoc msg = new StringBuilder JavaDoc();
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     /** Scan of all classes to check if they held statically things like Images or ResourceBundles
306      */

307     public void testStaticRefs() throws Exception JavaDoc {
308         JavaClass clz;
309         
310         // TODO need to exclude some usages that are justified
311

312         Set JavaDoc<Violation> violations = new TreeSet JavaDoc<Violation>();
313         for (File JavaDoc 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") // issue #96439
327
|| f.getName().endsWith("org-netbeans-modules-websvc-core.jar") // issue #96453
328
|| f.getName().endsWith("org-netbeans-modules-websvc-jaxrpc.jar")
329                     || f.getName().endsWith("org-netbeans-modules-j2ee-sun-appsrv.jar") // issue #96439
330
|| f.getName().endsWith("org-netbeans-modules-j2ee-sun-appsrv81.jar")
331                     || f.getName().endsWith("org-netbeans-modules-j2ee-ejbjarproject.jar") // issue #96423
332
|| 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") // issue #96427
340
|| f.getName().endsWith("org-netbeans-modules-web-core-syntax.jar")
341                     || f.getName().endsWith("org-netbeans-modules-java-source.jar") // issue #96461
342
|| 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")) { // issue #96422
346
continue;
347             }
348             JarFile JavaDoc jar = new JarFile JavaDoc(f);
349             Enumeration JavaDoc<JarEntry JavaDoc> entries = jar.entries();
350             JarEntry JavaDoc 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()) // default node icon si OK
355
|| "org/openide/awt/JInlineMenu.class".equals(entry.getName()) // empty icon si OK
356
|| "org/openide/awt/DynaMenuModel.class".equals(entry.getName()) // empty icon si OK
357
|| "org/netbeans/swing/tabcontrol/TabData.class".equals(entry.getName()) // empty icon si OK
358
|| "org/openide/explorer/propertysheet/PropertySheet.class".equals(entry.getName())) { // deprecated kept for compat
359
continue;
360                     } else if (entry.getName().startsWith("org/netbeans/modules/editor/java/JavaCompletionItem")) { // #96442
361
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 JavaDoc msg = new StringBuilder JavaDoc();
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     /** Check that we are not loading classes hungrily.
387      * DataLoader(String) is prefered to avoid loading of DataObject classes.
388      */

389     public void testDataLoaders() throws Exception JavaDoc {
390         Enumeration JavaDoc<DataLoader> loaders = DataLoaderPool.getDefault().allLoaders();
391         while (loaders.hasMoreElements()) {
392             DataLoader ldr = loaders.nextElement();
393             try {
394                 // XXX not enough better is to test that all ctors only call super(String)
395
Constructor JavaDoc ctor = ldr.getClass().getDeclaredConstructor(Class JavaDoc.class);
396                 assertNull(ldr.getClass().getName()+".<init>(String) is better are usualy enough", ctor);
397             } catch (NoSuchMethodException JavaDoc ex) {
398                 // expected path - OK
399
}
400         }
401     }
402 }
403
Popular Tags