1 19 package org.netbeans; 20 21 import java.io.IOException ; 22 import java.net.URL ; 23 import java.util.Enumeration ; 24 import java.util.Set ; 25 import junit.framework.TestCase; 26 27 31 public class JarClassLoaderTest extends TestCase { 32 33 public JarClassLoaderTest(String testName) { 34 super(testName); 35 } 36 37 public void testTwoClassloadersLoadTheSameSealedPackage() throws Exception { 38 String c = "org.openide.util.Cancellable"; 39 String 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 { 60 String c = "org.openide.util.Cancellable"; 61 String 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 { 83 doDependingClasses(true); 84 } 85 public void testTwoClassloadersLoadTheSamePackageForClassesThatDependOnEachOtherInReverseOrder() throws Exception { 86 doDependingClasses(false); 87 } 88 89 private void doDependingClasses(boolean smallerFirst) throws Exception { 90 Set above = new java.util.HashSet (); 91 String c = "org.openide.util.Task"; 92 above.add ("org.openide.util.Cancellable"); 93 above.add (c); 94 95 String 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 119 public static class OneClassLoader extends ProxyClassLoader { 120 121 private Set classes; 122 123 private boolean isSealed; 124 125 private ClassLoader loadClassLoader; 126 127 private String name; 128 129 public OneClassLoader(String name, ClassLoader l, String classname) { 130 this(name, l, new ClassLoader [] { l }, classname); 131 } 132 133 public OneClassLoader(String name, ClassLoader l, ClassLoader l2, String classname) { 134 this(name, l, new ClassLoader [] { l2 }, classname); 135 } 136 137 public OneClassLoader(String name, ClassLoader l, ClassLoader l2, Set names) { 138 this(name, l, new ClassLoader [] { l2 }, names); 139 } 140 141 public OneClassLoader(String name, ClassLoader lc, ClassLoader [] arr, String classname) { 142 this(name, lc, arr, java.util.Collections.singleton(classname)); 143 } 144 public OneClassLoader(String name, ClassLoader lc, ClassLoader [] arr, java.util.Set names) { 145 super(arr); 146 classes = names; 147 this.loadClassLoader = lc; 148 this.name = name; 149 } 150 151 153 protected boolean isSpecialResource(String pkg) { 154 return true; 155 } 156 157 162 163 164 protected Class simpleFindClass(String name, String path, String pkgnameSlashes) { 165 if (classes.contains (name)) { 166 try { 167 java.net.URL u = loadClassLoader.getResource(name.replace('.', '/') + ".class"); 168 assertNotNull ("URL cannot be null", u); 169 java.net.URLConnection 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 byte[] d = PatchByteCode.patch (data, name); 177 data = d; 178 179 int j = name.lastIndexOf('.'); 180 String pkgName = name.substring(0, j); 181 Package pkg = getPackageFast(pkgName, pkgnameSlashes, isSpecialResource(pkgnameSlashes)); 188 if (pkg != null) { 189 if (pkg.isSealed() && isSealed) throw new SecurityException ("sealing violation"); } else { 192 definePackage(pkgName, null, null, null, null, null, null, null); 193 } 194 195 return defineClass (name, data, 0, data.length, null); } catch (IOException ex) { 197 ex.printStackTrace(); 198 } 199 } 200 return null; 201 } 202 protected URL findResource(String name) { 204 return null; 205 } 206 207 protected Enumeration simpleFindResources(String name) { 208 return org.openide.util.Enumerations.empty(); 209 } 210 211 public String toString() { 212 return name; 213 } 214 } 215 216 public void testLoadingCLLearns() { 217 TrackingProxyClassLoader a = new TrackingProxyClassLoader ( 221 null, 222 new ClassLoader [] { getClass().getClassLoader().getParent() }); 223 TrackingProxyClassLoader b = new TrackingProxyClassLoader ( 224 getClass().getClassLoader(), 225 new ClassLoader [] { a }); 226 TrackingProxyClassLoader c = new TrackingProxyClassLoader ( 227 null, 228 new ClassLoader [] { b }); 229 Class loaded = null; 230 try { 231 loaded = c.loadClass("org.fakepkg.LoaderProbe"); 232 } catch (ClassNotFoundException 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 loaded2 = null; 240 try { 241 loaded = b.loadClass("org.fakepkg.LoaderProbe2"); 242 } catch (ClassNotFoundException 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 TrackingProxyClassLoader a = new TrackingProxyClassLoader ( 256 null, 257 new ClassLoader [] { getClass().getClassLoader().getParent() }); 258 TrackingProxyClassLoader b = new TrackingProxyClassLoader ( 259 getClass().getClassLoader(), 260 new ClassLoader [] { a }); 261 TrackingProxyClassLoader c = new TrackingProxyClassLoader ( 262 null, 263 new ClassLoader [] { b }); 264 URL 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 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 [] { getClass().getClassLoader().getParent() }); 280 URL url = a.getResource("javax/swing/text/html/default.css"); 281 assertNotNull("javax/swing/text/html/default.css was not loaded", url); 282 } 283 284 287 public static class TrackingProxyClassLoader extends ProxyClassLoader { 288 289 private int counterClasses = 0; 290 291 private int counterResources = 0; 292 293 private ClassLoader delegate; 294 295 public TrackingProxyClassLoader(ClassLoader delegate, ClassLoader [] 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 simpleFindClass(String name, String fileName, String pkg) { 307 counterClasses++; 308 if (delegate != null) { 309 try { 310 return delegate.loadClass(name); 311 } catch (ClassNotFoundException ex) { 312 } 315 } 316 return null; 317 } 318 319 protected URL findResource(String name) { 320 counterResources++; 321 return (delegate != null)? delegate.getResource(name): null; 322 } 323 324 } 325 } 326 | Popular Tags |