URLClassLoaderTest.java revision 743fc438ecba5ee39e44e4e8b36dfbe9381340bd
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 dalvik.annotation.BrokenTest; 21import dalvik.annotation.SideEffect; 22import dalvik.annotation.TestLevel; 23import dalvik.annotation.TestTargetClass; 24import dalvik.annotation.TestTargetNew; 25import dalvik.annotation.TestTargets; 26 27import org.apache.harmony.security.tests.support.TestCertUtils; 28 29import tests.support.Support_Configuration; 30import tests.support.Support_PortManager; 31import tests.support.Support_TestWebData; 32import tests.support.Support_TestWebServer; 33import tests.support.resource.Support_Resources; 34 35import java.io.File; 36import java.io.FileOutputStream; 37import java.io.IOException; 38import java.io.InputStream; 39import java.net.MalformedURLException; 40import java.net.URL; 41import java.net.URLClassLoader; 42import java.net.URLStreamHandler; 43import java.net.URLStreamHandlerFactory; 44import java.security.CodeSource; 45import java.security.Permission; 46import java.security.PermissionCollection; 47import java.security.cert.Certificate; 48import java.util.ArrayList; 49import java.util.Enumeration; 50import java.util.List; 51import java.util.Vector; 52import java.util.jar.Manifest; 53 54@TestTargetClass( 55 value = URLClassLoader.class, 56 untestedMethods = { 57 @TestTargetNew( 58 level = TestLevel.NOT_NECESSARY, 59 notes = "findClass uses defineClass which is not implemented", 60 method = "findClass", 61 args = {java.lang.String.class} 62 ) 63 } 64) 65public class URLClassLoaderTest extends junit.framework.TestCase { 66 67 class BogusClassLoader extends ClassLoader { 68 public URL getResource(String res) { 69 try { 70 return new URL("http://test/BogusClassLoader"); 71 } catch (MalformedURLException e) { 72 return null; 73 } 74 } 75 } 76 77 public class URLClassLoaderExt extends URLClassLoader { 78 79 public URLClassLoaderExt(URL[] urls) { 80 super(urls); 81 } 82 83 public Class<?> findClass(String cl) throws ClassNotFoundException { 84 return super.findClass(cl); 85 } 86 } 87 88 URLClassLoader ucl; 89 SecurityManager sm = new SecurityManager() { 90 91 public void checkPermission(Permission perm) { 92 } 93 94 public void checkCreateClassLoader() { 95 throw new SecurityException(); 96 } 97 }; 98 99 /** 100 * @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[]) 101 */ 102 @TestTargetNew( 103 level = TestLevel.COMPLETE, 104 notes = "", 105 method = "URLClassLoader", 106 args = {java.net.URL[].class} 107 ) 108 public void test_Constructor$Ljava_net_URL() throws MalformedURLException { 109 URL[] u = new URL[0]; 110 ucl = new URLClassLoader(u); 111 assertTrue("Failed to set parent", ucl != null 112 && ucl.getParent() == URLClassLoader.getSystemClassLoader()); 113 114 115 URL [] urls = {new URL("http://foo.com/foo"), 116 new URL("jar:file://foo.jar!/foo.c"), 117 new URL("ftp://foo1/foo2/foo.c")}; 118 119 URLClassLoader ucl1 = new URLClassLoader(urls); 120 assertTrue(urls.length == ucl1.getURLs().length); 121 122 try { 123 Class.forName("test", false, ucl); 124 fail("Should throw ClassNotFoundException"); 125 } catch (ClassNotFoundException e) { 126 // expected 127 } 128 129 SecurityManager oldSm = System.getSecurityManager(); 130 System.setSecurityManager(sm); 131 try { 132 new URLClassLoader(u); 133 fail("SecurityException should be thrown."); 134 } catch (SecurityException e) { 135 // expected 136 } finally { 137 System.setSecurityManager(oldSm); 138 } 139 140 try { 141 new URLClassLoader(new URL[] { null }); 142 } catch(Exception e) { 143 fail("Unexpected exception was thrown: " + e.getMessage()); 144 } 145 } 146 147 /** 148 * @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[], 149 * java.lang.ClassLoader) 150 */ 151 @TestTargetNew( 152 level = TestLevel.COMPLETE, 153 notes = "", 154 method = "URLClassLoader", 155 args = {java.net.URL[].class, java.lang.ClassLoader.class} 156 ) 157 public void test_Constructor$Ljava_net_URLLjava_lang_ClassLoader() { 158 ClassLoader cl = new BogusClassLoader(); 159 URL[] u = new URL[0]; 160 ucl = new URLClassLoader(u, cl); 161 URL res = ucl.getResource("J"); 162 assertNotNull(res); 163 assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile()); 164 165 SecurityManager oldSm = System.getSecurityManager(); 166 System.setSecurityManager(sm); 167 try { 168 new URLClassLoader(u, cl); 169 fail("SecurityException should be thrown."); 170 } catch (SecurityException e) { 171 // expected 172 } finally { 173 System.setSecurityManager(oldSm); 174 } 175 } 176 177 /** 178 * @tests java.net.URLClassLoader#findResources(java.lang.String) 179 */ 180 @TestTargetNew( 181 level = TestLevel.COMPLETE, 182 notes = "IOException checking missing. " 183 + "A test case that loads a resource from a webserver is missing.", 184 method = "findResources", 185 args = {java.lang.String.class} 186 ) 187 @SideEffect("Support_TestWebServer requires isolation.") 188 public void test_findResourcesLjava_lang_String() throws Exception { 189 Enumeration<URL> res = null; 190 String[] resValues = { "This is a test resource file.", 191 "This is a resource from a subdir"}; 192 193 String tmp = System.getProperty("java.io.tmpdir") + "/"; 194 195 File tmpDir = new File(tmp); 196 File test1 = new File(tmp + "test0"); 197 test1.deleteOnExit(); 198 FileOutputStream out = new FileOutputStream(test1); 199 out.write(resValues[0].getBytes()); 200 out.flush(); 201 out.close(); 202 203 File subDir = new File(tmp + "subdir/"); 204 subDir.mkdir(); 205 File test2 = new File(tmp + "subdir/test0"); 206 test2.deleteOnExit(); 207 out = new FileOutputStream(test2); 208 out.write(resValues[1].getBytes()); 209 out.flush(); 210 out.close(); 211 212 URL[] urls = new URL[2]; 213 urls[0] = new URL("file://" + tmpDir.getAbsolutePath() + "/"); 214 urls[1] = new URL("file://" + subDir.getAbsolutePath() + "/"); 215 216 ucl = new URLClassLoader(urls); 217 res = ucl.findResources("test0"); 218 assertNotNull("Failed to locate resources", res); 219 220 int i = 0; 221 while (res.hasMoreElements()) { 222 StringBuffer sb = getResContent(res.nextElement()); 223 assertEquals("Returned incorrect resource/or in wrong order", 224 resValues[i++], sb.toString()); 225 } 226 assertEquals("Incorrect number of resources returned", 2, i); 227 } 228 229 /** 230 * @tests java.net.URLClassLoader#getURLs() 231 */ 232 @TestTargetNew( 233 level = TestLevel.COMPLETE, 234 notes = "", 235 method = "getURLs", 236 args = {} 237 ) 238 public void test_getURLs() throws MalformedURLException { 239 URL[] urls = new URL[4]; 240 urls[0] = new URL("http://" + Support_Configuration.HomeAddress); 241 urls[1] = new URL("http://" + Support_Configuration.TestResources + "/"); 242 urls[2] = new URL("ftp://" + Support_Configuration.TestResources + "/"); 243 urls[3] = new URL("jar:file:c://" + Support_Configuration.TestResources 244 + "!/"); 245 ucl = new URLClassLoader(urls); 246 URL[] ucUrls = ucl.getURLs(); 247 for (int i = 0; i < urls.length; i++) { 248 assertEquals("Returned incorrect URL[]", urls[i], ucUrls[i]); 249 } 250 } 251 252 /** 253 * @tests java.net.URLClassLoader#newInstance(java.net.URL[]) 254 */ 255 @TestTargetNew( 256 level = TestLevel.COMPLETE, 257 notes = "", 258 method = "newInstance", 259 args = {java.net.URL[].class} 260 ) 261 @BrokenTest("web address used from support doesn't work anymore") 262 public void test_newInstance$Ljava_net_URL() throws MalformedURLException, 263 ClassNotFoundException { 264 // Verify that loaded class' have correct permissions 265 Class cl = null; 266 URL res = null; 267 URL[] urls = new URL[1]; 268 urls[0] = new URL(Support_Resources.getResourceURL("/UCL/UCL.jar")); 269 ucl = URLClassLoader.newInstance(urls); 270 cl = ucl.loadClass("ucl.ResClass"); 271 272 res = cl.getClassLoader().getResource("XX.class"); 273 assertNotNull("Failed to load class", cl); 274 assertNotNull( 275 "Loaded class unable to access resource from same codeSource", 276 res); 277 cl = null; 278 279 urls[0] = new URL("jar:" 280 + Support_Resources.getResourceURL("/UCL/UCL.jar!/")); 281 ucl = URLClassLoader.newInstance(urls); 282 cl = ucl.loadClass("ucl.ResClass"); 283 assertNotNull("Failed to load class from explicit jar URL", cl); 284 } 285 286 /** 287 * @tests java.net.URLClassLoader#newInstance(java.net.URL[], 288 * java.lang.ClassLoader) 289 */ 290 @TestTargetNew( 291 level = TestLevel.COMPLETE, 292 notes = "", 293 method = "newInstance", 294 args = {java.net.URL[].class, java.lang.ClassLoader.class} 295 ) 296 public void test_newInstance$Ljava_net_URLLjava_lang_ClassLoader() { 297 ClassLoader cl = new BogusClassLoader(); 298 URL[] u = new URL[0]; 299 ucl = URLClassLoader.newInstance(u, cl); 300 URL res = ucl.getResource("J"); 301 assertNotNull(res); 302 assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile()); 303 } 304 305 /** 306 * @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[], 307 * java.lang.ClassLoader, java.net.URLStreamHandlerFactory) 308 */ 309 @TestTargetNew( 310 level = TestLevel.COMPLETE, 311 notes = "", 312 method = "URLClassLoader", 313 args = {java.net.URL[].class, java.lang.ClassLoader.class, 314 java.net.URLStreamHandlerFactory.class} 315 ) 316 public void test_Constructor$Ljava_net_URLLjava_lang_ClassLoaderLjava_net_URLStreamHandlerFactory() { 317 class TestFactory implements URLStreamHandlerFactory { 318 public URLStreamHandler createURLStreamHandler(String protocol) { 319 return null; 320 } 321 } 322 ClassLoader cl = new BogusClassLoader(); 323 URL[] u = new URL[0]; 324 ucl = new URLClassLoader(u, cl, new TestFactory()); 325 URL res = ucl.getResource("J"); 326 assertNotNull(res); 327 assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile()); 328 329 SecurityManager oldSm = System.getSecurityManager(); 330 System.setSecurityManager(sm); 331 try { 332 new URLClassLoader(u, cl, new TestFactory()); 333 fail("SecurityException should be thrown."); 334 } catch (SecurityException e) { 335 // expected 336 } finally { 337 System.setSecurityManager(oldSm); 338 } 339 } 340 341 @TestTargetNew( 342 level = TestLevel.COMPLETE, 343 notes = "", 344 method = "addURL", 345 args = { URL.class } 346 ) 347 public void test_addURLLjava_net_URL() throws MalformedURLException { 348 URL[] u = new URL[0]; 349 350 URL [] urls = {new URL("http://foo.com/foo"), 351 new URL("jar:file://foo.jar!/foo.c"), 352 new URL("ftp://foo1/foo2/foo.c"), null}; 353 354 TestURLClassLoader tucl = new TestURLClassLoader(u); 355 356 for(int i = 0; i < urls.length;) { 357 tucl.addURL(urls[i]); 358 i++; 359 URL [] result = tucl.getURLs(); 360 assertEquals("Result array length is incorrect: " + i, 361 i, result.length); 362 for(int j = 0; j < result.length; j++) { 363 assertEquals("Result array item is incorrect: " + j, 364 urls[j], result[j]); 365 } 366 } 367 } 368 369 @TestTargetNew( 370 level = TestLevel.SUFFICIENT, 371 notes = "", 372 method = "getPermissions", 373 args = { CodeSource.class } 374 ) 375 public void test_getPermissions() throws MalformedURLException { 376 URL url = new URL("http://" + Support_Configuration.SpecialInetTestAddress); 377 Certificate[] chain = TestCertUtils.getCertChain(); 378 CodeSource cs = new CodeSource(url, chain); 379 TestURLClassLoader cl = new TestURLClassLoader(new URL[] {url}); 380 PermissionCollection permCol = cl.getPermissions(cs); 381 assertNotNull(permCol); 382 383 URL url1 = new URL("file://foo/foo.c"); 384 TestURLClassLoader cl1 = new TestURLClassLoader(new URL[] {url}); 385 CodeSource cs1 = new CodeSource(url1, chain); 386 PermissionCollection permCol1 = cl1.getPermissions(cs1); 387 assertNotNull(permCol1); 388 } 389 390 @TestTargetNew( 391 level = TestLevel.COMPLETE, 392 notes = "", 393 method = "definePackage", 394 args = { java.lang.String.class, java.util.jar.Manifest.class, 395 java.net.URL.class } 396 ) 397 public void test_definePackage() throws MalformedURLException { 398 Manifest manifest = new Manifest(); 399 URL[] u = new URL[0]; 400 TestURLClassLoader tucl = new TestURLClassLoader(u); 401 402 URL [] urls = {new URL("http://foo.com/foo"), 403 new URL("jar:file://foo.jar!/foo.c"), 404 new URL("ftp://foo1/foo2/foo.c"), 405 new URL("file://new/package/name/"), 406 null}; 407 408 String packageName = "new.package.name"; 409 410 for(int i = 0; i < urls.length; i++) { 411 Package pack = tucl.definePackage(packageName + i, manifest, urls[i]); 412 assertEquals(packageName + i, pack.getName()); 413 assertNull("Implementation Title is not null", 414 pack.getImplementationTitle()); 415 assertNull("Implementation Vendor is not null", 416 pack.getImplementationVendor()); 417 assertNull("Implementation Version is not null.", 418 pack.getImplementationVersion()); 419 } 420 421 try { 422 tucl.definePackage(packageName + "0", manifest, null); 423 fail("IllegalArgumentException was not thrown."); 424 } catch(IllegalArgumentException iae) { 425 //expected 426 } 427 } 428 429 class TestURLClassLoader extends URLClassLoader { 430 public TestURLClassLoader(URL[] urls) { 431 super(urls); 432 } 433 434 public void addURL(URL url) { 435 super.addURL(url); 436 } 437 438 public Package definePackage(String name, 439 Manifest man, 440 URL url) 441 throws IllegalArgumentException { 442 return super.definePackage(name, man, url); 443 } 444 445 public Class<?> findClass(String name) 446 throws ClassNotFoundException { 447 return super.findClass(name); 448 } 449 450 protected PermissionCollection getPermissions(CodeSource codesource) { 451 return super.getPermissions(codesource); 452 } 453 } 454 455 /** 456 * @tests java.net.URLClassLoader#findResource(java.lang.String) 457 */ 458 @TestTargetNew( 459 level = TestLevel.PARTIAL_COMPLETE, 460 notes = "", 461 method = "findResource", 462 args = {java.lang.String.class} 463 ) 464 @SideEffect("Support_TestWebServer requires isolation.") 465 public void test_findResourceLjava_lang_String() throws Exception { 466 int port = Support_PortManager.getNextPort(); 467 File tmp = File.createTempFile("test", ".txt"); 468 469 Support_TestWebServer server = new Support_TestWebServer(); 470 try { 471 472 server.initServer(port, tmp.getAbsolutePath(), "text/html"); 473 474 URL[] urls = { new URL("http://localhost:" + port + "/") }; 475 ucl = new URLClassLoader(urls); 476 URL res = ucl.findResource("test1"); 477 assertNotNull("Failed to locate resource", res); 478 479 StringBuffer sb = getResContent(res); 480 assertEquals("Returned incorrect resource", new String(Support_TestWebData.test1), 481 sb.toString()); 482 } finally { 483 server.close(); 484 } 485 } 486 487 @TestTargets({ 488 @TestTargetNew( 489 level = TestLevel.PARTIAL, 490 notes = "Checks getResource, indirectly checks findResource", 491 clazz = ClassLoader.class, 492 method = "getResource", 493 args = {java.lang.String.class} 494 ), 495 @TestTargetNew( 496 level = TestLevel.PARTIAL_COMPLETE, 497 notes = "Checks getResource, indirectly checks findResource", 498 method = "findResource", 499 args = {java.lang.String.class} 500 ) 501 }) 502 public void testFindResource_H3461() throws Exception { 503 File tmpDir = new File(System.getProperty("java.io.tmpdir")); 504 File dir = new File(tmpDir, "encode#me"); 505 File f, f2; 506 URLClassLoader loader; 507 URL dirUrl; 508 509 if (!dir.exists()) { 510 dir.mkdir(); 511 } 512 dir.deleteOnExit(); 513 dirUrl = dir.toURI().toURL(); 514 loader = new URLClassLoader( new URL[] { dirUrl }); 515 516 f = File.createTempFile("temp", ".dat", dir); 517 f.deleteOnExit(); 518 f2 = File.createTempFile("bad#name#", ".dat", dir); 519 f2.deleteOnExit(); 520 521 assertNotNull("Unable to load resource from path with problematic name", 522 loader.getResource(f.getName())); 523 assertEquals("URL was not correctly encoded", 524 f2.toURI().toURL(), 525 loader.getResource(f2.getName())); 526 } 527 528 /** 529 * @tests java.net.URLClassLoader#getResource(java.lang.String) 530 */ 531 @TestTargetNew( 532 level = TestLevel.COMPLETE, 533 notes = "", 534 method = "getResource", 535 args = {java.lang.String.class} 536 ) 537 public void test_getResourceLjava_lang_String() 538 throws MalformedURLException { 539 URL url1 = new URL("file:///"); 540 URLClassLoader loader = new URLClassLoader(new URL[] { url1 }); 541 long start = System.currentTimeMillis(); 542 // try without the leading / 543 URL result = loader.getResource("dir1/file1"); 544 long end = System.currentTimeMillis(); 545 long time = end - start; 546 if (time < 100) { 547 time = 100; 548 } 549 550 start = System.currentTimeMillis(); 551 // try with the leading forward slash 552 result = loader.getResource("/dir1/file1"); 553 end = System.currentTimeMillis(); 554 long uncTime = end - start; 555 assertTrue("too long. UNC path formed? UNC time: " + uncTime 556 + " regular time: " + time, uncTime <= (time * 4)); 557 } 558 559 /** 560 * Regression for Harmony-2237 561 */ 562 @TestTargetNew( 563 level = TestLevel.PARTIAL_COMPLETE, 564 notes = "Regression test", 565 method = "findResource", 566 args = {java.lang.String.class} 567 ) 568 @SideEffect("Support_TestWebServer requires isolation.") 569 public void test_findResource_String() throws Exception { 570 File tempFile1 = File.createTempFile("textFile", ".txt"); 571 tempFile1.createNewFile(); 572 tempFile1.deleteOnExit(); 573 File tempFile2 = File.createTempFile("jarFile", ".jar"); 574 tempFile2.delete(); 575 tempFile2.deleteOnExit(); 576 577 Support_TestWebServer server = new Support_TestWebServer(); 578 int port = Support_PortManager.getNextPort(); 579 try { 580 server.initServer(port, false); 581 582 String tempPath1 = tempFile1.getParentFile().getAbsolutePath() + "/"; 583 InputStream is = getClass().getResourceAsStream( 584 "/tests/resources/hyts_patch.jar"); 585 Support_Resources.copyLocalFileto(tempFile2, is); 586 String tempPath2 = tempFile2.getAbsolutePath(); 587 String tempPath3 = "http://localhost:" + port + "/"; 588 URLClassLoader urlLoader = getURLClassLoader(tempPath1, tempPath2); 589 assertNull("Found inexistant resource", 590 urlLoader.findResource("XXX")); //$NON-NLS-1$ 591 assertNotNull("Couldn't find resource from directory", 592 urlLoader.findResource(tempFile1.getName())); //$NON-NLS-1$ 593 assertNotNull("Couldn't find resource from jar", 594 urlLoader.findResource("Blah.txt")); //$NON-NLS-1$ 595 urlLoader = getURLClassLoader(tempPath1, tempPath2, tempPath3); 596 assertNotNull("Couldn't find resource from web", 597 urlLoader.findResource("test1")); //$NON-NLS-1$ 598 assertNull("Found inexistant resource from web", 599 urlLoader.findResource("test3")); //$NON-NLS-1$ 600 } finally { 601 server.close(); 602 } 603 } 604 605 private static URLClassLoader getURLClassLoader(String... classPath) 606 throws MalformedURLException { 607 List<URL> urlList = new ArrayList<URL>(); 608 for (String path : classPath) { 609 String url; 610 File f = new File(path); 611 if (f.isDirectory()) { 612 url = "file:" + path; 613 } else if (path.startsWith("http")) { 614 url = path; 615 } else { 616 url = "jar:file:" + path + "!/"; 617 } 618 urlList.add(new URL(url)); 619 } 620 return new URLClassLoader(urlList.toArray(new URL[urlList.size()])); 621 } 622 623 private StringBuffer getResContent(URL res) throws IOException { 624 StringBuffer sb = new StringBuffer(); 625 InputStream is = res.openStream(); 626 627 int c; 628 while ((c = is.read()) != -1) { 629 sb.append((char) c); 630 } 631 is.close(); 632 return sb; 633 } 634} 635