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 18 package org.apache.harmony.luni.tests.java.net; 19 20 import java.io.File; 21 import java.io.FileOutputStream; 22 import java.io.IOException; 23 import java.io.InputStream; 24 import java.net.MalformedURLException; 25 import java.net.URL; 26 import java.net.URLClassLoader; 27 import java.net.URLStreamHandler; 28 import java.net.URLStreamHandlerFactory; 29 import java.util.Enumeration; 30 import java.util.NoSuchElementException; 31 import java.util.StringTokenizer; 32 import java.util.Vector; 33 import java.util.jar.Attributes; 34 import java.util.jar.JarFile; 35 import java.util.jar.JarOutputStream; 36 import java.util.jar.Manifest; 37 38 import junit.framework.TestCase; 39 import tests.support.Support_Configuration; 40 import tests.support.Support_Jetty; 41 import tests.support.resource.Support_Resources; 42 43 public class URLClassLoaderTest extends TestCase { 44 45 private static final String PREFIX = "http://localhost:"; 46 47 private static final String ROOT = "resources/net.resources/HTTP/html/testres231"; 48 49 private static String serverURL = null; 50 51 URLClassLoader ucl; 52 53 static { 54 int port = 0; 55 try { 56 port = Support_Jetty.startHttpServerWithDocRoot(ROOT); 57 } catch (Exception e) { 58 fail("Exception during setup jetty : " + e.getMessage()); 59 } 60 serverURL = PREFIX + port + "/"; 61 } 62 63 class BogusClassLoader extends ClassLoader { getResource(String res)64 public URL getResource(String res) { 65 try { 66 return new URL("http://test/BogusClassLoader"); 67 } catch (MalformedURLException e) { 68 return null; 69 } 70 } 71 } 72 73 public class URLClassLoaderExt extends URLClassLoader { 74 URLClassLoaderExt(URL[] urls)75 public URLClassLoaderExt(URL[] urls) { 76 super(urls); 77 } 78 findClass(String cl)79 public Class<?> findClass(String cl) throws ClassNotFoundException { 80 return super.findClass(cl); 81 } 82 } 83 84 /** 85 * @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[]) 86 */ test_Constructor$Ljava_net_URL()87 public void test_Constructor$Ljava_net_URL() throws Exception { 88 URL[] u = new URL[0]; 89 ucl = new URLClassLoader(u); 90 assertNotNull(ucl); 91 assertSame("Failed to set parent", URLClassLoader 92 .getSystemClassLoader(), ucl.getParent()); 93 94 URLClassLoader loader = new URLClassLoader(new URL[] { null }); 95 try { 96 Class.forName("test", false, loader); 97 fail("Should throw NullPointerException"); 98 } catch (NullPointerException e) { 99 // Expected 100 } 101 } 102 103 /** 104 * @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[], 105 *java.lang.ClassLoader) 106 */ test_Constructor$Ljava_net_URLLjava_lang_ClassLoader()107 public void test_Constructor$Ljava_net_URLLjava_lang_ClassLoader() { 108 ClassLoader cl = new BogusClassLoader(); 109 URL[] u = new URL[0]; 110 ucl = new URLClassLoader(u, cl); 111 URL res = ucl.getResource("J"); 112 assertNotNull(res); 113 assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile()); 114 } 115 116 /** 117 * @tests java.net.URLClassLoader#findResources(java.lang.String) 118 */ test_findResourcesLjava_lang_String()119 public void test_findResourcesLjava_lang_String() throws IOException { 120 String[] resValues = { "This is a test resource file.", 121 "This is a resource from a subdir" }; 122 URL[] urls = new URL[2]; 123 urls[0] = new URL(serverURL); 124 urls[1] = new URL(serverURL + "/subdir1/"); 125 ucl = new URLClassLoader(urls); 126 Enumeration res = ucl.findResources("RESOURCE.TXT"); 127 assertNotNull("Failed to locate resources", res); 128 129 int i = 0; 130 while (res.hasMoreElements()) { 131 StringBuffer sb = new StringBuffer(); 132 InputStream is = ((URL) res.nextElement()).openStream(); 133 int c; 134 while ((c = is.read()) != -1) { 135 sb.append((char) c); 136 } 137 assertEquals("Returned incorrect resource/or in wrong order", 138 resValues[i++], sb.toString()); 139 } 140 assertEquals("Incorrect number of resources returned: " + i, 2, i); 141 142 // Regression for HARMONY-6510 143 res = ucl.findResources(null); 144 assertNotNull(res); 145 assertFalse(res.hasMoreElements()); 146 } 147 148 /** 149 * @tests java.net.URLClassLoader#getURLs() 150 */ test_getURLs()151 public void test_getURLs() throws MalformedURLException { 152 URL[] urls = new URL[4]; 153 urls[0] = new URL("http://" + Support_Configuration.HomeAddress); 154 urls[1] = new URL("http://" + Support_Configuration.TestResources + "/"); 155 urls[2] = new URL("ftp://" + Support_Configuration.TestResources + "/"); 156 urls[3] = new URL("jar:file:c://" + Support_Configuration.TestResources 157 + "!/"); 158 ucl = new URLClassLoader(urls); 159 URL[] ucUrls = ucl.getURLs(); 160 for (int i = 0; i < urls.length; i++) { 161 assertEquals("Returned incorrect URL[]", urls[i], ucUrls[i]); 162 } 163 } 164 165 /** 166 * @tests java.net.URLClassLoader#newInstance(java.net.URL[]) 167 */ test_newInstance$Ljava_net_URL()168 public void test_newInstance$Ljava_net_URL() throws MalformedURLException, 169 ClassNotFoundException { 170 // Verify that loaded class' have correct permissions 171 URL[] urls = new URL[1]; 172 urls[0] = new URL(serverURL + "/UCL/UCL.jar"); 173 ucl = URLClassLoader.newInstance(urls); 174 Class cl = ucl.loadClass("ucl.ResClass"); 175 176 URL res = cl.getClassLoader().getResource("XX.class"); 177 assertNotNull("Failed to load class", cl); 178 assertNotNull( 179 "Loaded class unable to access resource from same codeSource", 180 res); 181 cl = null; 182 urls[0] = new URL("jar:" + serverURL + "/UCL/UCL.jar!/"); 183 ucl = URLClassLoader.newInstance(urls); 184 cl = ucl.loadClass("ucl.ResClass"); 185 assertNotNull("Failed to load class from explicit jar URL", cl); 186 } 187 188 /** 189 * @tests java.net.URLClassLoader#newInstance(java.net.URL[], 190 *java.lang.ClassLoader) 191 */ test_newInstance$Ljava_net_URLLjava_lang_ClassLoader()192 public void test_newInstance$Ljava_net_URLLjava_lang_ClassLoader() { 193 ClassLoader cl = new BogusClassLoader(); 194 URL[] u = new URL[0]; 195 ucl = URLClassLoader.newInstance(u, cl); 196 URL res = ucl.getResource("J"); 197 assertNotNull(res); 198 assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile()); 199 } 200 201 /** 202 * @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[], 203 *java.lang.ClassLoader, java.net.URLStreamHandlerFactory) 204 */ test_Constructor$Ljava_net_URLLjava_lang_ClassLoaderLjava_net_URLStreamHandlerFactory()205 public void test_Constructor$Ljava_net_URLLjava_lang_ClassLoaderLjava_net_URLStreamHandlerFactory() { 206 class TestFactory implements URLStreamHandlerFactory { 207 public URLStreamHandler createURLStreamHandler(String protocol) { 208 return null; 209 } 210 } 211 ClassLoader cl = new BogusClassLoader(); 212 URL[] u = new URL[0]; 213 ucl = new URLClassLoader(u, cl, new TestFactory()); 214 URL res = ucl.getResource("J"); 215 assertNotNull(res); 216 assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile()); 217 } 218 219 /** 220 * @throws ClassNotFoundException 221 * @throws IOException 222 * @tests java.net.URLClassLoader#findClass(java.lang.String) 223 */ test_findClassLjava_lang_String()224 public void test_findClassLjava_lang_String() 225 throws ClassNotFoundException, IOException { 226 File resources = Support_Resources.createTempFolder(); 227 String resPath = resources.toString(); 228 if (resPath.charAt(0) == '/' || resPath.charAt(0) == '\\') { 229 resPath = resPath.substring(1); 230 } 231 Support_Resources.copyFile(resources, "JarIndex", "hyts_11.jar"); 232 Support_Resources.copyFile(resources, "JarIndex", "hyts_12.jar"); 233 Support_Resources.copyFile(resources, "JarIndex", "hyts_13.jar"); 234 Support_Resources.copyFile(resources, "JarIndex", "hyts_14.jar"); 235 236 URL[] urls = new URL[1]; 237 urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_11.jar"); 238 URLClassLoader ucl = URLClassLoader.newInstance(urls, null); 239 240 URL resURL = ucl.findResource("Test.txt"); 241 URL reference = new URL("jar:file:/" + resPath.replace('\\', '/') 242 + "/JarIndex/hyts_14.jar!/Test.txt"); 243 assertEquals("Resource not found: " + resURL + " ref: " + reference, 244 reference, resURL); 245 246 assertNotNull(Class.forName("cpack.CNothing", true, ucl)); 247 248 Support_Resources.copyFile(resources, "JarIndex", "hyts_21.jar"); 249 Support_Resources.copyFile(resources, "JarIndex", "hyts_22.jar"); 250 Support_Resources.copyFile(resources, "JarIndex", "hyts_23.jar"); 251 urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_21.jar"); 252 ucl = URLClassLoader.newInstance(urls, null); 253 Enumeration en = ucl.findResources("bpack/"); 254 255 boolean resourcesFound; 256 try { 257 resourcesFound = true; 258 URL url1 = (URL) en.nextElement(); 259 URL url2 = (URL) en.nextElement(); 260 resourcesFound = resourcesFound 261 && url1.equals(new URL("jar:file:/" 262 + resPath.replace('\\', '/') 263 + "/JarIndex/hyts_22.jar!/bpack/")); 264 resourcesFound = resourcesFound 265 && url2.equals(new URL("jar:file:/" 266 + resPath.replace('\\', '/') 267 + "/JarIndex/hyts_23.jar!/bpack/")); 268 if (en.hasMoreElements()) { 269 resourcesFound = false; 270 } 271 } catch (NoSuchElementException e) { 272 resourcesFound = false; 273 } 274 assertTrue("Resources not found (1)", resourcesFound); 275 276 assertNotNull(Class.forName("bpack.Homer", true, ucl)); 277 278 try { 279 Class.forName("bpack.Bart", true, ucl); 280 fail("should throw ClassNotFoundException"); 281 } catch (ClassNotFoundException e) { 282 // Expected 283 } 284 285 try { 286 Class.forName("Main4", true, ucl); 287 fail("should throw ClassNotFoundException"); 288 } catch (ClassNotFoundException e) { 289 // Expected 290 } 291 292 Support_Resources.copyFile(resources, "JarIndex", "hyts_22-new.jar"); 293 urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_22-new.jar"); 294 ucl = URLClassLoader.newInstance(urls, null); 295 assertNotNull("Cannot find resource", ucl.findResource("cpack/")); 296 Support_Resources.copyFile(resources, "JarIndex", "hyts_11.jar"); 297 urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_31.jar"); 298 ucl = URLClassLoader.newInstance(urls, null); 299 300 try { 301 Class.forName("cpack.Mock", true, ucl); 302 fail("should throw ClassNotFoundException"); 303 } catch (ClassNotFoundException e) { 304 // Expected 305 } 306 307 // testing circular reference 308 Support_Resources.copyFile(resources, "JarIndex", "hyts_41.jar"); 309 Support_Resources.copyFile(resources, "JarIndex", "hyts_42.jar"); 310 urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_41.jar"); 311 ucl = URLClassLoader.newInstance(urls, null); 312 en = ucl.findResources("bpack/"); 313 resourcesFound = resourcesFound 314 && ((URL) en.nextElement()).equals(new URL("jar:file:/" 315 + resPath.replace('\\', '/') 316 + "/JarIndex/hyts_42.jar!/bpack/")); 317 assertTrue("Resources not found (2)", resourcesFound); 318 assertFalse("No more resources expected", en.hasMoreElements()); 319 320 // Regression test for HARMONY-2357. 321 try { 322 URLClassLoaderExt cl = new URLClassLoaderExt(new URL[557]); 323 cl.findClass("0"); 324 fail("should throw NullPointerException"); 325 } catch (NullPointerException npe) { 326 // Expected 327 } 328 329 // Regression test for HARMONY-2871. 330 URLClassLoader cl = new URLClassLoader(new URL[] { new URL( 331 "file:/foo.jar") }); 332 333 try { 334 Class.forName("foo.Foo", false, cl); 335 } catch (Exception ex) { 336 // Ignored 337 } 338 339 try { 340 Class.forName("foo.Foo", false, cl); 341 fail("should throw ClassNotFoundException"); 342 } catch (ClassNotFoundException cnfe) { 343 // Expected 344 } 345 } 346 347 /** 348 * @tests java.net.URLClassLoader#findResource(java.lang.String) 349 */ test_findResourceLjava_lang_String()350 public void test_findResourceLjava_lang_String() 351 throws MalformedURLException { 352 URL[] urls = new URL[2]; 353 urls[0] = new URL(serverURL); 354 urls[1] = new URL(serverURL); 355 ucl = new URLClassLoader(urls); 356 URL res = ucl.findResource("RESOURCE.TXT"); 357 assertNotNull("Failed to locate resource", res); 358 359 StringBuffer sb = new StringBuffer(); 360 try { 361 java.io.InputStream is = res.openStream(); 362 363 int c; 364 while ((c = is.read()) != -1) { 365 sb.append((char) c); 366 } 367 is.close(); 368 } catch (IOException e) { 369 } 370 assertTrue("Returned incorrect resource", !sb.toString().equals( 371 "This is a test resource file")); 372 } 373 testFindResource_H3461()374 public void testFindResource_H3461() throws Exception { 375 File userDir = new File(System.getProperty("user.dir")); 376 File dir = new File(userDir, "encode#me"); 377 File f, f2; 378 URLClassLoader loader; 379 URL dirUrl; 380 381 if (!dir.exists()) { 382 dir.mkdir(); 383 } 384 dir.deleteOnExit(); 385 dirUrl = dir.toURI().toURL(); 386 loader = new URLClassLoader(new URL[] { dirUrl }); 387 388 f = File.createTempFile("temp", ".dat", dir); 389 f.deleteOnExit(); 390 f2 = File.createTempFile("bad#name#", ".dat", dir); 391 f2.deleteOnExit(); 392 393 assertNotNull( 394 "Unable to load resource from path with problematic name", 395 loader.getResource(f.getName())); 396 assertEquals("URL was not correctly encoded", f2.toURI().toURL(), 397 loader.getResource(f2.getName())); 398 } 399 test_findResource()400 public void test_findResource() throws Exception { 401 File resources = Support_Resources.createTempFolder(); 402 String resPath = resources.toString(); 403 if (resPath.charAt(0) == '/' || resPath.charAt(0) == ' ') { 404 resPath = resPath.substring(1); 405 } 406 Support_Resources.copyFile(resources, "JarIndex", "hyts_21.jar"); 407 Support_Resources.copyFile(resources, "JarIndex", "hyts_22.jar"); 408 Support_Resources.copyFile(resources, "JarIndex", "hyts_23.jar"); 409 410 URLClassLoader urlClassloader = URLClassLoader.newInstance( 411 new URL[] { new URL("file:/" + resPath 412 + "/JarIndex/hyts_21.jar") }, null); 413 Enumeration en = urlClassloader.findResources("bpack/"); 414 assertTrue(en.hasMoreElements()); 415 URL expected = new URL("jar:file:/" + resPath.replace('\\', '/') 416 + "/JarIndex/hyts_22.jar!/bpack/"); 417 assertEquals(expected, (URL) en.nextElement()); 418 assertEquals(expected, urlClassloader.findResource("bpack/")); 419 } 420 421 /** 422 * @tests java.net.URLClassLoader#getResource(java.lang.String) 423 */ test_getResourceLjava_lang_String()424 public void test_getResourceLjava_lang_String() 425 throws MalformedURLException { 426 URL url1 = new URL("file:///"); 427 URLClassLoader loader = new URLClassLoader(new URL[] { url1 }, null); 428 long start = System.currentTimeMillis(); 429 // try without the leading / 430 URL result = loader.getResource("dir1/file1"); 431 long end = System.currentTimeMillis(); 432 long time = end - start; 433 if (time < 100) { 434 time = 100; 435 } 436 437 start = System.currentTimeMillis(); 438 // try with the leading forward slash 439 result = loader.getResource("/dir1/file1"); 440 end = System.currentTimeMillis(); 441 long uncTime = end - start; 442 assertTrue("too long. UNC path formed? UNC time: " + uncTime 443 + " regular time: " + time, uncTime <= (time * 4)); 444 } 445 446 /** 447 * Regression for Harmony-2237 448 */ test_getResource()449 public void test_getResource() throws Exception { 450 URLClassLoader urlLoader = getURLClassLoader(); 451 assertNull(urlLoader.findResource("XXX")); //$NON-NLS-1$ 452 } 453 getURLClassLoader()454 private static URLClassLoader getURLClassLoader() { 455 String classPath = System.getProperty("java.class.path"); 456 StringTokenizer tok = new StringTokenizer(classPath, File.pathSeparator); 457 Vector<URL> urlVec = new Vector<URL>(); 458 String resPackage = Support_Resources.RESOURCE_PACKAGE; 459 try { 460 while (tok.hasMoreTokens()) { 461 String path = tok.nextToken(); 462 String url; 463 if (new File(path).isDirectory()) 464 url = "file:" + path + resPackage + "subfolder/"; 465 else 466 url = "jar:file:" + path + "!" + resPackage + "subfolder/"; 467 urlVec.addElement(new URL(url)); 468 } 469 } catch (MalformedURLException e) { 470 // do nothing 471 } 472 URL[] urls = new URL[urlVec.size()]; 473 for (int i = 0; i < urlVec.size(); i++) { 474 urls[i] = urlVec.elementAt(i); 475 } 476 URLClassLoader loader = new URLClassLoader(urls, null); 477 return loader; 478 } 479 480 /** 481 * Regression test for HARMONY-2255 482 */ test_getResourceAsStream()483 public void test_getResourceAsStream() { 484 InputStream in = this.getClass() 485 .getResourceAsStream("test%.properties"); 486 assertNotNull(in); 487 in = this.getClass().getResourceAsStream("test%25.properties"); 488 assertNull(in); 489 } 490 491 /** 492 * Regression test for HARMONY-6074 493 */ test_findClassLjava_lang_String_Jar_Class_Path()494 public void test_findClassLjava_lang_String_Jar_Class_Path() throws Exception { 495 File resources = Support_Resources.createTempFolder(); 496 String resPath = resources.toString(); 497 if (resPath.charAt(0) == '/' || resPath.charAt(0) == '\\') { 498 resPath = resPath.substring(1); 499 } 500 501 Support_Resources.copyFile(resources, "JarIndex", "hyts_11.jar"); 502 Support_Resources.copyFile(resources, "JarIndex", "hyts_13.jar"); 503 504 JarFile jarFile = new JarFile(resources.getAbsolutePath() + "/JarIndex/hyts_11.jar"); 505 Manifest mf = jarFile.getManifest(); 506 Attributes attrs = mf.getMainAttributes(); 507 attrs.putValue("Class-Path", "file:/" + resPath + "/JarIndex/hyts_13.jar"); 508 509 File mainJar = new File(resources.getAbsolutePath() + "/JarIndex/main.jar"); 510 JarOutputStream jos = new JarOutputStream(new FileOutputStream(mainJar), mf); 511 jos.flush(); 512 jos.close(); 513 assertTrue(mainJar.exists()); 514 515 URL[] urls = new URL[1]; 516 urls[0] = new URL("file:/" + resPath + "/JarIndex/main.jar"); 517 ucl = URLClassLoader.newInstance(urls, null); 518 assertNotNull(Class.forName("Main2", true, ucl)); 519 } 520 521 } 522