KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > JarClassLoaderTest


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 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans;
20
21 import java.io.IOException JavaDoc;
22 import java.net.URL JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.Set JavaDoc;
25 import junit.framework.TestCase;
26
27 /**
28  *
29  * @author Jaroslav Tulach
30  */

31 public class JarClassLoaderTest extends TestCase {
32
33     public JarClassLoaderTest(String JavaDoc testName) {
34         super(testName);
35     }
36
37     public void testTwoClassloadersLoadTheSameSealedPackage() throws Exception JavaDoc {
38         String JavaDoc c = "org.openide.util.Cancellable";
39         String JavaDoc g = "org.openide.util.ContextGlobalProvider";
40
41         OneClassLoader cancel = new OneClassLoader (
42             "cancel loader", getClass().getClassLoader(), getClass().getClassLoader().getParent(), c
43         );
44         
45         OneClassLoader global = new OneClassLoader (
46             "global that delegates to cancel", getClass().getClassLoader(), cancel, g
47         );
48
49         assertNotNull("Loads the class", cancel.loadClass(c, true));
50         assertNotNull("Loads global", global.loadClass(g, true));
51         assertEquals("Right CL for cancel", cancel, cancel.loadClass(c, true).getClassLoader());
52         assertEquals("Right CL for global", global, global.loadClass(g, true).getClassLoader());
53         
54         assertEquals("Loads the same cancel", cancel.loadClass(c, true), global.loadClass(c, true));
55         
56         
57     }
58     
59     public void testTwoClassloadersLoadTheSameSealedPackageInReverseOrder() throws Exception JavaDoc {
60         String JavaDoc c = "org.openide.util.Cancellable";
61         String JavaDoc g = "org.openide.util.ContextGlobalProvider";
62         
63         OneClassLoader cancel = new OneClassLoader (
64             "cancel loader", getClass().getClassLoader(), getClass().getClassLoader().getParent(), c
65         );
66         
67         OneClassLoader global = new OneClassLoader (
68             "global that delegates to cancel", getClass().getClassLoader(), cancel, g
69         );
70
71         assertNotNull("Loads global", global.loadClass(g, true));
72         assertEquals("Right CL for global", global, global.loadClass(g, true).getClassLoader());
73
74         assertNotNull("Loads the class", cancel.loadClass(c, true));
75         assertEquals("Right CL for cancel", cancel, cancel.loadClass(c, true).getClassLoader());
76         
77         assertEquals("Loads the same cancel", cancel.loadClass(c, true), global.loadClass(c, true));
78         
79         
80     }
81
82     public void testTwoClassloadersLoadTheSamePackageForClassesThatDependOnEachOther() throws Exception JavaDoc {
83         doDependingClasses(true);
84     }
85     public void testTwoClassloadersLoadTheSamePackageForClassesThatDependOnEachOtherInReverseOrder() throws Exception JavaDoc {
86         doDependingClasses(false);
87     }
88     
89     private void doDependingClasses(boolean smallerFirst) throws Exception JavaDoc {
90         Set JavaDoc above = new java.util.HashSet JavaDoc();
91         String JavaDoc c = "org.openide.util.Task";
92         above.add ("org.openide.util.Cancellable");
93         above.add (c);
94         
95         String JavaDoc g = "org.openide.util.RequestProcessor$Task";
96         
97         OneClassLoader cancel = new OneClassLoader (
98             "cancel loader", getClass().getClassLoader(), getClass().getClassLoader().getParent(), above
99         );
100         
101         OneClassLoader global = new OneClassLoader (
102             "global that delegates to cancel", getClass().getClassLoader(), cancel, g
103         );
104         
105         if (smallerFirst) {
106             assertNotNull("Loads the class", cancel.loadClass(c, true));
107             assertEquals("Right CL for cancel", cancel, cancel.loadClass(c, true).getClassLoader());
108         }
109         
110
111         assertNotNull("Loads global", global.loadClass(g, true));
112         assertEquals("Right CL for global", global, global.loadClass(g, true).getClassLoader());
113
114         assertEquals("Loads the same cancel", cancel.loadClass(c, true), global.loadClass(c, true));
115     }
116     
117     /** Loads one class from the parent class loader, by itself.
118      */

119     public static class OneClassLoader extends ProxyClassLoader {
120         /** set of Strings that we accept */
121         private Set JavaDoc classes;
122         /** is sealed */
123         private boolean isSealed;
124         /** classloader to load class */
125         private ClassLoader JavaDoc loadClassLoader;
126         /** name */
127         private String JavaDoc name;
128         
129         public OneClassLoader(String JavaDoc name, ClassLoader JavaDoc l, String JavaDoc classname) {
130             this(name, l, new ClassLoader JavaDoc[] { l }, classname);
131         }
132         
133         public OneClassLoader(String JavaDoc name, ClassLoader JavaDoc l, ClassLoader JavaDoc l2, String JavaDoc classname) {
134             this(name, l, new ClassLoader JavaDoc[] { l2 }, classname);
135         }
136         
137         public OneClassLoader(String JavaDoc name, ClassLoader JavaDoc l, ClassLoader JavaDoc l2, Set JavaDoc names) {
138             this(name, l, new ClassLoader JavaDoc[] { l2 }, names);
139         }
140         
141         public OneClassLoader(String JavaDoc name, ClassLoader JavaDoc lc, ClassLoader JavaDoc[] arr, String JavaDoc classname) {
142             this(name, lc, arr, java.util.Collections.singleton(classname));
143         }
144         public OneClassLoader(String JavaDoc name, ClassLoader JavaDoc lc, ClassLoader JavaDoc[] arr, java.util.Set JavaDoc names) {
145             super(arr);
146             classes = names;
147             this.loadClassLoader = lc;
148             this.name = name;
149         }
150     
151         /** For our test all packages are special.
152          */

153         protected boolean isSpecialResource(String JavaDoc pkg) {
154             return true;
155         }
156
157         /** Allows to specify the right permissions, OneModuleClassLoader does it differently.
158          *
159         protected PermissionCollection getPermissions( CodeSource cs ) {
160             return Policy.getPolicy().getPermissions(cs);
161         } */

162
163
164         protected Class JavaDoc simpleFindClass(String JavaDoc name, String JavaDoc path, String JavaDoc pkgnameSlashes) {
165             if (classes.contains (name)) {
166               try {
167                 java.net.URL JavaDoc u = loadClassLoader.getResource(name.replace('.', '/') + ".class");
168                 assertNotNull ("URL cannot be null", u);
169                 java.net.URLConnection JavaDoc c = u.openConnection();
170                 int l = c.getContentLength();
171                 byte[] data = new byte[l];
172                 int cnt = c.getInputStream().read (data);
173                 assertEquals ("Read the same as expected", l, cnt);
174                 
175                 // do the enhancing
176
byte[] d = PatchByteCode.patch (data, name);
177                 data = d;
178
179                 int j = name.lastIndexOf('.');
180                 String JavaDoc pkgName = name.substring(0, j);
181                 // Note that we assume that if we are defining a class in this package,
182
// we should also define the package! Thus recurse==false.
183
// However special packages might be defined in a parent and then we want
184
// to have the same Package object, proper sealing check, etc.; so be safe,
185
// overhead is probably small (check in parents, nope, check super which
186
// delegates to system loaders).
187
Package JavaDoc pkg = getPackageFast(pkgName, pkgnameSlashes, isSpecialResource(pkgnameSlashes));
188                 if (pkg != null) {
189                     // XXX full sealing check, URLClassLoader does something more
190
if (pkg.isSealed() && isSealed) throw new SecurityException JavaDoc("sealing violation"); // NOI18N
191
} else {
192                     definePackage(pkgName, null, null, null, null, null, null, null);
193                 }
194
195                 return defineClass (name, data, 0, data.length, null); //getProtectionDomain());
196
} catch (IOException JavaDoc ex) {
197                   ex.printStackTrace();
198               }
199             }
200             return null;
201         }
202         // look up the jars and return a resource based on a content of jars
203
protected URL JavaDoc findResource(String JavaDoc name) {
204             return null;
205         }
206
207         protected Enumeration JavaDoc simpleFindResources(String JavaDoc name) {
208             return org.openide.util.Enumerations.empty();
209         }
210         
211         public String JavaDoc toString() {
212             return name;
213         }
214     }
215     
216     public void testLoadingCLLearns() {
217         // create 3CLs: A <- B <- C
218
// load something from B using C - it should ask A then B
219
// load from the same package using B - A should not be asked
220
TrackingProxyClassLoader a = new TrackingProxyClassLoader (
221                 null,
222                 new ClassLoader JavaDoc [] { getClass().getClassLoader().getParent() });
223         TrackingProxyClassLoader b = new TrackingProxyClassLoader (
224                 getClass().getClassLoader(),
225                 new ClassLoader JavaDoc [] { a });
226         TrackingProxyClassLoader c = new TrackingProxyClassLoader (
227                 null,
228                 new ClassLoader JavaDoc [] { b });
229         Class JavaDoc loaded = null;
230         try {
231             loaded = c.loadClass("org.fakepkg.LoaderProbe");
232         } catch (ClassNotFoundException JavaDoc ex) {
233             fail("org.fakepkg.LoaderProbe was not loaded");
234         }
235         assertNotNull("org.fakepkg.LoaderProbe was not loaded", loaded);
236         assertEquals("a should be asked once", 1, a.getClassLoadCount());
237         assertEquals("b should be asked once", 1, b.getClassLoadCount());
238         assertEquals("c should not be asked", 0, c.getClassLoadCount());
239         Class JavaDoc loaded2 = null;
240         try {
241             loaded = b.loadClass("org.fakepkg.LoaderProbe2");
242         } catch (ClassNotFoundException JavaDoc ex) {
243             fail("org.fakepkg.LoaderProbe2 was not loaded");
244         }
245         assertNotNull("org.fakepkg.LoaderProbe2 was not loaded", loaded);
246         assertEquals("a should be asked once", 1, a.getClassLoadCount());
247         assertEquals("b should be asked twice", 2, b.getClassLoadCount());
248         assertEquals("c should not be asked", 0, c.getClassLoadCount());
249     }
250
251     public void testLoadingCLLearnsDuringGetResource() {
252         // create 3CLs: A <- B <- C
253
// load something from B using C - it should ask A then B
254
// load from the same package using B - A should not be asked
255
TrackingProxyClassLoader a = new TrackingProxyClassLoader (
256                 null,
257                 new ClassLoader JavaDoc [] { getClass().getClassLoader().getParent() });
258         TrackingProxyClassLoader b = new TrackingProxyClassLoader (
259                 getClass().getClassLoader(),
260                 new ClassLoader JavaDoc [] { a });
261         TrackingProxyClassLoader c = new TrackingProxyClassLoader (
262                 null,
263                 new ClassLoader JavaDoc [] { b });
264         URL JavaDoc url = c.getResource("org/fakepkg/resource1.txt");
265         assertNotNull("org/fakepkg/resource1.txt was not loaded", url);
266         assertEquals("a should be asked once", 1, a.getFindeResourceCount());
267         assertEquals("b should be asked once", 1, b.getFindeResourceCount());
268         assertEquals("c should not be asked", 0, c.getFindeResourceCount());
269         URL JavaDoc url2 = b.getResource("org/fakepkg/resource2.txt");
270         assertNotNull("org/fakepkg/resource2.txt was not loaded", url2);
271         assertEquals("a should be asked once", 1, a.getFindeResourceCount());
272         assertEquals("b should be asked twice", 2, b.getFindeResourceCount());
273         assertEquals("c should not be asked", 0, c.getFindeResourceCount());
274     }
275     
276     public void testLearningGetResource () {
277         TrackingProxyClassLoader a = new TrackingProxyClassLoader (
278                 null,
279                 new ClassLoader JavaDoc [] { getClass().getClassLoader().getParent() });
280         URL JavaDoc url = a.getResource("javax/swing/text/html/default.css");
281         assertNotNull("javax/swing/text/html/default.css was not loaded", url);
282     }
283
284     /** Testing ClassLoader loader.
285      * Either loads from parent or delegates to some suplied ClassLoader.
286      */

287     public static class TrackingProxyClassLoader extends ProxyClassLoader {
288         
289         private int counterClasses = 0;
290         
291         private int counterResources = 0;
292         
293         private ClassLoader JavaDoc delegate;
294         
295         public TrackingProxyClassLoader(ClassLoader JavaDoc delegate, ClassLoader JavaDoc[] parents ) {
296             super(parents);
297             this.delegate = delegate;
298         }
299
300         public int getClassLoadCount() {
301             return counterClasses;
302         }
303         public int getFindeResourceCount() {
304             return counterResources;
305         }
306         protected Class JavaDoc simpleFindClass(String JavaDoc name, String JavaDoc fileName, String JavaDoc pkg) {
307             counterClasses++;
308             if (delegate != null) {
309                 try {
310                     return delegate.loadClass(name);
311                 } catch (ClassNotFoundException JavaDoc ex) {
312                     // not a problem
313
// ex.printStackTrace();
314
}
315             }
316             return null;
317         }
318
319         protected URL JavaDoc findResource(String JavaDoc name) {
320             counterResources++;
321             return (delegate != null)? delegate.getResource(name): null;
322         }
323         
324     }
325 }
326
Popular Tags