URLClassLoaderTest.java revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package tests.api.java.net; 19 20import java.io.File; 21import java.io.IOException; 22import java.io.InputStream; 23import java.net.MalformedURLException; 24import java.net.URI; 25import java.net.URL; 26import java.net.URLClassLoader; 27import java.net.URLStreamHandler; 28import java.net.URLStreamHandlerFactory; 29import java.util.Enumeration; 30import java.util.NoSuchElementException; 31import java.util.StringTokenizer; 32import java.util.Vector; 33 34import org.apache.harmony.luni.util.InvalidJarIndexException; 35 36import tests.support.Support_Configuration; 37import tests.support.resource.Support_Resources; 38 39public class URLClassLoaderTest extends junit.framework.TestCase { 40 41 class BogusClassLoader extends ClassLoader { 42 public URL getResource(String res) { 43 try { 44 return new URL("http://test/BogusClassLoader"); 45 } catch (MalformedURLException e) { 46 return null; 47 } 48 } 49 } 50 51 public class URLClassLoaderExt extends URLClassLoader { 52 53 public URLClassLoaderExt(URL[] urls) { 54 super(urls); 55 } 56 57 public Class<?> findClass(String cl) throws ClassNotFoundException { 58 return super.findClass(cl); 59 } 60 } 61 62 URLClassLoader ucl; 63 64 /** 65 * @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[]) 66 */ 67 public void test_Constructor$Ljava_net_URL() { 68 URL[] u = new URL[0]; 69 ucl = new URLClassLoader(u); 70 assertTrue("Failed to set parent", ucl != null 71 && ucl.getParent() == URLClassLoader.getSystemClassLoader()); 72 73 URLClassLoader loader = new URLClassLoader(new URL[] { null }); 74 boolean exception = false; 75 try { 76 Class.forName("test", false, loader); 77 fail("Should throw ClassNotFoundException"); 78 } catch (ClassNotFoundException e) { 79 // expected 80 } 81 } 82 83 /** 84 * @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[], 85 * java.lang.ClassLoader) 86 */ 87 public void test_Constructor$Ljava_net_URLLjava_lang_ClassLoader() { 88 ClassLoader cl = new BogusClassLoader(); 89 URL[] u = new URL[0]; 90 ucl = new URLClassLoader(u, cl); 91 URL res = ucl.getResource("J"); 92 assertNotNull(res); 93 assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile()); 94 } 95 96 /** 97 * @tests java.net.URLClassLoader#findResources(java.lang.String) 98 */ 99 public void test_findResourcesLjava_lang_String() throws IOException { 100 Enumeration res = null; 101 String[] resValues = { "This is a test resource file.", 102 "This is a resource from a subdir" }; 103 104 URL[] urls = new URL[2]; 105 urls[0] = new URL(Support_Resources.getResourceURL("/")); 106 urls[1] = new URL(Support_Resources.getResourceURL("/subdir1/")); 107 ucl = new URLClassLoader(urls); 108 res = ucl.findResources("RESOURCE.TXT"); 109 assertNotNull("Failed to locate resources", res); 110 111 int i = 0; 112 while (res.hasMoreElements()) { 113 StringBuffer sb = new StringBuffer(); 114 InputStream is = ((URL) res.nextElement()).openStream(); 115 int c; 116 while ((c = is.read()) != -1) { 117 sb.append((char) c); 118 } 119 assertEquals("Returned incorrect resource/or in wrong order", 120 resValues[i++], sb.toString()); 121 } 122 assertTrue("Incorrect number of resources returned: " + i, i == 2); 123 } 124 125 /** 126 * @tests java.net.URLClassLoader#getURLs() 127 */ 128 public void test_getURLs() throws MalformedURLException { 129 URL[] urls = new URL[4]; 130 urls[0] = new URL("http://" + Support_Configuration.HomeAddress); 131 urls[1] = new URL("http://" + Support_Configuration.TestResources + "/"); 132 urls[2] = new URL("ftp://" + Support_Configuration.TestResources + "/"); 133 urls[3] = new URL("jar:file:c://" + Support_Configuration.TestResources 134 + "!/"); 135 ucl = new URLClassLoader(urls); 136 URL[] ucUrls = ucl.getURLs(); 137 for (int i = 0; i < urls.length; i++) { 138 assertEquals("Returned incorrect URL[]", urls[i], ucUrls[i]); 139 } 140 } 141 142 /** 143 * @tests java.net.URLClassLoader#newInstance(java.net.URL[]) 144 */ 145 public void test_newInstance$Ljava_net_URL() throws MalformedURLException, 146 ClassNotFoundException { 147 // Verify that loaded class' have correct permissions 148 Class cl = null; 149 URL res = null; 150 URL[] urls = new URL[1]; 151 urls[0] = new URL(Support_Resources.getResourceURL("/UCL/UCL.jar")); 152 ucl = URLClassLoader.newInstance(urls); 153 cl = ucl.loadClass("ucl.ResClass"); 154 155 res = cl.getClassLoader().getResource("XX.class"); 156 assertNotNull("Failed to load class", cl); 157 assertNotNull( 158 "Loaded class unable to access resource from same codeSource", 159 res); 160 cl = null; 161 162 urls[0] = new URL("jar:" 163 + Support_Resources.getResourceURL("/UCL/UCL.jar!/")); 164 ucl = URLClassLoader.newInstance(urls); 165 cl = ucl.loadClass("ucl.ResClass"); 166 assertNotNull("Failed to load class from explicit jar URL", cl); 167 } 168 169 /** 170 * @tests java.net.URLClassLoader#newInstance(java.net.URL[], 171 * java.lang.ClassLoader) 172 */ 173 public void test_newInstance$Ljava_net_URLLjava_lang_ClassLoader() { 174 ClassLoader cl = new BogusClassLoader(); 175 URL[] u = new URL[0]; 176 ucl = URLClassLoader.newInstance(u, cl); 177 URL res = ucl.getResource("J"); 178 assertNotNull(res); 179 assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile()); 180 } 181 182 /** 183 * @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[], 184 * java.lang.ClassLoader, java.net.URLStreamHandlerFactory) 185 */ 186 public void test_Constructor$Ljava_net_URLLjava_lang_ClassLoaderLjava_net_URLStreamHandlerFactory() { 187 class TestFactory implements URLStreamHandlerFactory { 188 public URLStreamHandler createURLStreamHandler(String protocol) { 189 return null; 190 } 191 } 192 ClassLoader cl = new BogusClassLoader(); 193 URL[] u = new URL[0]; 194 ucl = new URLClassLoader(u, cl, new TestFactory()); 195 URL res = ucl.getResource("J"); 196 assertNotNull(res); 197 assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile()); 198 } 199 200 /** 201 * @throws ClassNotFoundException 202 * @throws IOException 203 * @tests java.net.URLClassLoader#findClass(java.lang.String) 204 */ 205 public void test_findClassLjava_lang_String() 206 throws ClassNotFoundException, IOException { 207 File resources = Support_Resources.createTempFolder(); 208 String resPath = resources.toString(); 209 if (resPath.charAt(0) == '/' || resPath.charAt(0) == '\\') { 210 resPath = resPath.substring(1); 211 } 212 213 java.net.URL[] urls = new java.net.URL[1]; 214 java.net.URLClassLoader ucl = null; 215 boolean classFound; 216 boolean exception; 217 boolean goodException; 218 Enumeration en; 219 boolean resourcesFound; 220 Support_Resources.copyFile(resources, "JarIndex", "hyts_11.jar"); 221 Support_Resources.copyFile(resources, "JarIndex", "hyts_12.jar"); 222 Support_Resources.copyFile(resources, "JarIndex", "hyts_13.jar"); 223 Support_Resources.copyFile(resources, "JarIndex", "hyts_14.jar"); 224 urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_11.jar"); 225 ucl = URLClassLoader.newInstance(urls, null); 226 URL resURL = ucl.findResource("Test.txt"); 227 URL reference = new URL("jar:file:/" + resPath.replace('\\', '/') 228 + "/JarIndex/hyts_14.jar!/Test.txt"); 229 assertTrue("Resource not found: " + resURL + " ref: " + reference, 230 resURL.equals(reference)); 231 232 Class c = Class.forName("cpack.CNothing", true, ucl); 233 assertNotNull(c); 234 235 Support_Resources.copyFile(resources, "JarIndex", "hyts_21.jar"); 236 Support_Resources.copyFile(resources, "JarIndex", "hyts_22.jar"); 237 Support_Resources.copyFile(resources, "JarIndex", "hyts_23.jar"); 238 urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_21.jar"); 239 ucl = URLClassLoader.newInstance(urls, null); 240 en = ucl.findResources("bpack/"); 241 242 try { 243 resourcesFound = true; 244 URL url1 = (URL) en.nextElement(); 245 URL url2 = (URL) en.nextElement(); 246 System.out.println(url1); 247 System.out.println(url2); 248 resourcesFound = resourcesFound 249 && url1.equals(new URL("jar:file:/" 250 + resPath.replace('\\', '/') 251 + "/JarIndex/hyts_22.jar!/bpack/")); 252 resourcesFound = resourcesFound 253 && url2.equals(new URL("jar:file:/" 254 + resPath.replace('\\', '/') 255 + "/JarIndex/hyts_23.jar!/bpack/")); 256 if (en.hasMoreElements()) { 257 resourcesFound = false; 258 } 259 } catch (NoSuchElementException e) { 260 resourcesFound = false; 261 } 262 assertTrue("Resources not found (1)", resourcesFound); 263 264 Class c2 = Class.forName("bpack.Homer", true, ucl); 265 assertNotNull(c2); 266 267 try { 268 Class.forName("bpack.Bart", true, ucl); 269 fail("InvalidJarIndexException should be thrown"); 270 } catch (InvalidJarIndexException e) { 271 // expected 272 } 273 274 try { 275 Class.forName("Main4", true, ucl); 276 fail("ClassNotFoundException should be thrown"); 277 } catch (ClassNotFoundException e) { 278 // Expected 279 } 280 281 Support_Resources.copyFile(resources, "JarIndex", "hyts_22-new.jar"); 282 urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_22-new.jar"); 283 ucl = URLClassLoader.newInstance(urls, null); 284 assertNotNull("Cannot find resource", ucl.findResource("cpack/")); 285 Support_Resources.copyFile(resources, "JarIndex", "hyts_11.jar"); 286 urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_31.jar"); 287 ucl = URLClassLoader.newInstance(urls, null); 288 289 try { 290 Class.forName("cpack.Mock", true, ucl); 291 fail("ClassNotFoundException should be thrown"); 292 } catch (ClassNotFoundException e) { 293 // Expected 294 } 295 296 // testing circular reference 297 Support_Resources.copyFile(resources, "JarIndex", "hyts_41.jar"); 298 Support_Resources.copyFile(resources, "JarIndex", "hyts_42.jar"); 299 urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_41.jar"); 300 ucl = URLClassLoader.newInstance(urls, null); 301 en = ucl.findResources("bpack/"); 302 resourcesFound = resourcesFound 303 && ((URL) en.nextElement()).equals(new URL("jar:file:/" 304 + resPath.replace('\\', '/') 305 + "/JarIndex/hyts_42.jar!/bpack/")); 306 assertTrue("Resources not found (2)", resourcesFound); 307 assertFalse("No more resources expected", en.hasMoreElements()); 308 309 // Regression test for HARMONY-2357. 310 try { 311 URLClassLoaderExt cl = new URLClassLoaderExt(new URL[557]); 312 cl.findClass("0"); 313 fail("NullPointerException should be thrown"); 314 } catch (NullPointerException npe) { 315 // Expected 316 } 317 318 // Regression test for HARMONY-2871. 319 URLClassLoader cl = new URLClassLoader(new URL[] { new URL("file:/foo.jar") }); 320 321 try { 322 Class.forName("foo.Foo", false, cl); 323 } catch (Exception ex) { 324 // Don't care 325 } 326 327 try { 328 Class.forName("foo.Foo", false, cl); 329 fail("NullPointerException should be thrown"); 330 } catch (ClassNotFoundException cnfe) { 331 // Expected 332 } 333 } 334 335 /** 336 * @tests java.net.URLClassLoader#findResource(java.lang.String) 337 */ 338 public void test_findResourceLjava_lang_String() 339 throws MalformedURLException { 340 URL res = null; 341 342 URL[] urls = new URL[2]; 343 urls[0] = new URL("http://" + Support_Configuration.HomeAddress); 344 urls[1] = new URL(Support_Resources.getResourceURL("/")); 345 ucl = new URLClassLoader(urls); 346 res = ucl.findResource("RESOURCE.TXT"); 347 assertNotNull("Failed to locate resource", res); 348 349 StringBuffer sb = new StringBuffer(); 350 try { 351 java.io.InputStream is = res.openStream(); 352 353 int c; 354 while ((c = is.read()) != -1) { 355 sb.append((char) c); 356 } 357 is.close(); 358 } catch (IOException e) { 359 } 360 assertTrue("Returned incorrect resource", !sb.toString().equals( 361 "This is a test resource file")); 362 } 363 364 public void testFindResource_H3461() throws Exception { 365 File userDir = new File(System.getProperty("user.dir")); 366 File dir = new File(userDir, "encode#me"); 367 File f, f2; 368 URLClassLoader loader; 369 URL dirUrl; 370 371 if (!dir.exists()) { 372 dir.mkdir(); 373 } 374 dir.deleteOnExit(); 375 dirUrl = dir.toURI().toURL(); 376 loader = new URLClassLoader( new URL[] { dirUrl }); 377 378 f = File.createTempFile("temp", ".dat", dir); 379 f.deleteOnExit(); 380 f2 = File.createTempFile("bad#name#", ".dat", dir); 381 f2.deleteOnExit(); 382 383 assertNotNull("Unable to load resource from path with problematic name", 384 loader.getResource(f.getName())); 385 assertEquals("URL was not correctly encoded", 386 f2.toURI().toURL(), 387 loader.getResource(f2.getName())); 388 } 389 390 /** 391 * @tests java.net.URLClassLoader#getResource(java.lang.String) 392 */ 393 public void test_getResourceLjava_lang_String() 394 throws MalformedURLException { 395 URL url1 = new URL("file:///"); 396 URLClassLoader loader = new URLClassLoader(new URL[] { url1 }, null); 397 long start = System.currentTimeMillis(); 398 // try without the leading / 399 URL result = loader.getResource("dir1/file1"); 400 long end = System.currentTimeMillis(); 401 long time = end - start; 402 if (time < 100) { 403 time = 100; 404 } 405 406 start = System.currentTimeMillis(); 407 // try with the leading forward slash 408 result = loader.getResource("/dir1/file1"); 409 end = System.currentTimeMillis(); 410 long uncTime = end - start; 411 assertTrue("too long. UNC path formed? UNC time: " + uncTime 412 + " regular time: " + time, uncTime <= (time * 4)); 413 } 414 415 /** 416 * Regression for Harmony-2237 417 */ 418 public void test_getResource() throws Exception { 419 URLClassLoader urlLoader = getURLClassLoader(); 420 assertNull(urlLoader.findResource("XXX")); //$NON-NLS-1$ 421 } 422 423 private static URLClassLoader getURLClassLoader() { 424 String classPath = System.getProperty("java.class.path"); 425 StringTokenizer tok = new StringTokenizer(classPath, File.pathSeparator); 426 Vector<URL> urlVec = new Vector<URL>(); 427 String resPackage = Support_Resources.RESOURCE_PACKAGE; 428 try { 429 while (tok.hasMoreTokens()) { 430 String path = tok.nextToken(); 431 String url; 432 if (new File(path).isDirectory()) 433 url = "file:" + path + resPackage + "subfolder/"; 434 else 435 url = "jar:file:" + path + "!" + resPackage + "subfolder/"; 436 urlVec.addElement(new URL(url)); 437 } 438 } catch (MalformedURLException e) { 439 // do nothing 440 } 441 URL[] urls = new URL[urlVec.size()]; 442 for (int i = 0; i < urlVec.size(); i++) { 443 urls[i] = urlVec.elementAt(i); 444 } 445 URLClassLoader loader = new URLClassLoader(urls, null); 446 return loader; 447 } 448} 449