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 * Copyright (C) 2008 The Android Open Source Project 19 * 20 * Licensed under the Apache License, Version 2.0 (the "License"); 21 * you may not use this file except in compliance with the License. 22 * You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33 package java.lang; 34 35 import dalvik.system.PathClassLoader; 36 import dalvik.system.VMStack; 37 import java.io.IOException; 38 import java.io.InputStream; 39 import java.net.URL; 40 import java.nio.ByteBuffer; 41 import java.security.ProtectionDomain; 42 import java.util.Collection; 43 import java.util.Enumeration; 44 import java.util.HashMap; 45 import java.util.Map; 46 47 /** 48 * Loads classes and resources from a repository. One or more class loaders are 49 * installed at runtime. These are consulted whenever the runtime system needs a 50 * specific class that is not yet available in-memory. Typically, class loaders 51 * are grouped into a tree where child class loaders delegate all requests to 52 * parent class loaders. Only if the parent class loader cannot satisfy the 53 * request, the child class loader itself tries to handle it. 54 * <p> 55 * {@code ClassLoader} is an abstract class that implements the common 56 * infrastructure required by all class loaders. Android provides several 57 * concrete implementations of the class, with 58 * {@link dalvik.system.PathClassLoader} being the one typically used. Other 59 * applications may implement subclasses of {@code ClassLoader} to provide 60 * special ways for loading classes. 61 * </p> 62 * @see Class 63 */ 64 public abstract class ClassLoader { 65 66 // BEGIN android-note 67 /* 68 * Because of a potential class initialization race between ClassLoader and 69 * java.lang.System, reproducible when using JDWP with "suspend=y", we defer 70 * creation of the system class loader until first use. We use a static 71 * inner class to get synchronization at init time without having to sync on 72 * every access. 73 */ 74 // END android-note 75 /** 76 * The 'System' ClassLoader - the one that is responsible for loading 77 * classes from the classpath. It is not equal to the bootstrap class loader - 78 * that one handles the built-in classes. 79 * 80 * @see #getSystemClassLoader() 81 */ 82 static private class SystemClassLoader { 83 public static ClassLoader loader = ClassLoader.createSystemClassLoader(); 84 } 85 86 /** 87 * The parent ClassLoader. 88 */ 89 private ClassLoader parent; 90 91 /** 92 * The packages known to the class loader. 93 */ 94 private Map<String, Package> packages = new HashMap<String, Package>(); 95 96 /** 97 * Create the system class loader. Note this is NOT the bootstrap class 98 * loader (which is managed by the VM). We use a null value for the parent 99 * to indicate that the bootstrap loader is our parent. 100 */ createSystemClassLoader()101 private static ClassLoader createSystemClassLoader() { 102 String classPath = System.getProperty("java.class.path", "."); 103 104 // String[] paths = classPath.split(":"); 105 // URL[] urls = new URL[paths.length]; 106 // for (int i = 0; i < paths.length; i++) { 107 // try { 108 // urls[i] = new URL("file://" + paths[i]); 109 // } 110 // catch (Exception ex) { 111 // ex.printStackTrace(); 112 // } 113 // } 114 // 115 // return new java.net.URLClassLoader(urls, null); 116 117 // TODO Make this a java.net.URLClassLoader once we have those? 118 return new PathClassLoader(classPath, BootClassLoader.getInstance()); 119 } 120 121 /** 122 * Returns the system class loader. This is the parent for new 123 * {@code ClassLoader} instances and is typically the class loader used to 124 * start the application. If a security manager is present and the caller's 125 * class loader is neither {@code null} nor the same as or an ancestor of 126 * the system class loader, then this method calls the security manager's 127 * checkPermission method with a RuntimePermission("getClassLoader") 128 * permission to ensure that it is ok to access the system class loader. If 129 * not, a {@code SecurityException} is thrown. 130 * 131 * @return the system class loader. 132 * @throws SecurityException 133 * if a security manager exists and it does not allow access to 134 * the system class loader. 135 */ getSystemClassLoader()136 public static ClassLoader getSystemClassLoader() { 137 SecurityManager smgr = System.getSecurityManager(); 138 if (smgr != null) { 139 ClassLoader caller = VMStack.getCallingClassLoader(); 140 if (caller != null && !caller.isAncestorOf(SystemClassLoader.loader)) { 141 smgr.checkPermission(new RuntimePermission("getClassLoader")); 142 } 143 } 144 145 return SystemClassLoader.loader; 146 } 147 148 /** 149 * Finds the URL of the resource with the specified name. The system class 150 * loader's resource lookup algorithm is used to find the resource. 151 * 152 * @return the {@code URL} object for the requested resource or {@code null} 153 * if the resource can not be found. 154 * @param resName 155 * the name of the resource to find. 156 * @see Class#getResource 157 */ getSystemResource(String resName)158 public static URL getSystemResource(String resName) { 159 return SystemClassLoader.loader.getResource(resName); 160 } 161 162 /** 163 * Returns an enumeration of URLs for the resource with the specified name. 164 * The system class loader's resource lookup algorithm is used to find the 165 * resource. 166 * 167 * @return an enumeration of {@code URL} objects containing the requested 168 * resources. 169 * @param resName 170 * the name of the resource to find. 171 * @throws IOException 172 * if an I/O error occurs. 173 */ getSystemResources(String resName)174 public static Enumeration<URL> getSystemResources(String resName) throws IOException { 175 return SystemClassLoader.loader.getResources(resName); 176 } 177 178 /** 179 * Returns a stream for the resource with the specified name. The system 180 * class loader's resource lookup algorithm is used to find the resource. 181 * Basically, the contents of the java.class.path are searched in order, 182 * looking for a path which matches the specified resource. 183 * 184 * @return a stream for the resource or {@code null}. 185 * @param resName 186 * the name of the resource to find. 187 * @see Class#getResourceAsStream 188 */ getSystemResourceAsStream(String resName)189 public static InputStream getSystemResourceAsStream(String resName) { 190 return SystemClassLoader.loader.getResourceAsStream(resName); 191 } 192 193 /** 194 * Constructs a new instance of this class with the system class loader as 195 * its parent. 196 * 197 * @throws SecurityException 198 * if a security manager exists and it does not allow the 199 * creation of a new {@code ClassLoader}. 200 */ ClassLoader()201 protected ClassLoader() { 202 this(getSystemClassLoader(), false); 203 } 204 205 /** 206 * Constructs a new instance of this class with the specified class loader 207 * as its parent. 208 * 209 * @param parentLoader 210 * The {@code ClassLoader} to use as the new class loader's 211 * parent. 212 * @throws SecurityException 213 * if a security manager exists and it does not allow the 214 * creation of new a new {@code ClassLoader}. 215 */ ClassLoader(ClassLoader parentLoader)216 protected ClassLoader(ClassLoader parentLoader) { 217 this(parentLoader, false); 218 } 219 220 /* 221 * constructor for the BootClassLoader which needs parent to be null. 222 */ ClassLoader(ClassLoader parentLoader, boolean nullAllowed)223 ClassLoader(ClassLoader parentLoader, boolean nullAllowed) { 224 SecurityManager smgr = System.getSecurityManager(); 225 if (smgr != null) { 226 smgr.checkCreateClassLoader(); 227 } 228 229 if (parentLoader == null && !nullAllowed) { 230 throw new NullPointerException( 231 "Parent ClassLoader may not be null"); 232 } 233 234 parent = parentLoader; 235 } 236 237 /** 238 * Constructs a new class from an array of bytes containing a class 239 * definition in class file format. 240 * 241 * @param classRep 242 * the memory image of a class file. 243 * @param offset 244 * the offset into {@code classRep}. 245 * @param length 246 * the length of the class file. 247 * @return the {@code Class} object created from the specified subset of 248 * data in {@code classRep}. 249 * @throws ClassFormatError 250 * if {@code classRep} does not contain a valid class. 251 * @throws IndexOutOfBoundsException 252 * if {@code offset < 0}, {@code length < 0} or if 253 * {@code offset + length} is greater than the length of 254 * {@code classRep}. 255 * @deprecated Use {@link #defineClass(String, byte[], int, int)} 256 */ 257 @Deprecated defineClass(byte[] classRep, int offset, int length)258 protected final Class<?> defineClass(byte[] classRep, int offset, int length) 259 throws ClassFormatError { 260 261 return VMClassLoader.defineClass(this, classRep, offset, length, null); 262 } 263 264 /** 265 * Constructs a new class from an array of bytes containing a class 266 * definition in class file format. 267 * 268 * @param className 269 * the expected name of the new class, may be {@code null} if not 270 * known. 271 * @param classRep 272 * the memory image of a class file. 273 * @param offset 274 * the offset into {@code classRep}. 275 * @param length 276 * the length of the class file. 277 * @return the {@code Class} object created from the specified subset of 278 * data in {@code classRep}. 279 * @throws ClassFormatError 280 * if {@code classRep} does not contain a valid class. 281 * @throws IndexOutOfBoundsException 282 * if {@code offset < 0}, {@code length < 0} or if 283 * {@code offset + length} is greater than the length of 284 * {@code classRep}. 285 */ defineClass(String className, byte[] classRep, int offset, int length)286 protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length) 287 throws ClassFormatError { 288 289 // TODO Define a default ProtectionDomain on first use 290 return defineClass(className, classRep, offset, length, null); 291 } 292 293 /** 294 * Constructs a new class from an array of bytes containing a class 295 * definition in class file format and assigns the specified protection 296 * domain to the new class. If the provided protection domain is 297 * {@code null} then a default protection domain is assigned to the class. 298 * 299 * @param className 300 * the expected name of the new class, may be {@code null} if not 301 * known. 302 * @param classRep 303 * the memory image of a class file. 304 * @param offset 305 * the offset into {@code classRep}. 306 * @param length 307 * the length of the class file. 308 * @param protectionDomain 309 * the protection domain to assign to the loaded class, may be 310 * {@code null}. 311 * @return the {@code Class} object created from the specified subset of 312 * data in {@code classRep}. 313 * @throws ClassFormatError 314 * if {@code classRep} does not contain a valid class. 315 * @throws IndexOutOfBoundsException 316 * if {@code offset < 0}, {@code length < 0} or if 317 * {@code offset + length} is greater than the length of 318 * {@code classRep}. 319 * @throws NoClassDefFoundError 320 * if {@code className} is not equal to the name of the class 321 * contained in {@code classRep}. 322 */ defineClass(String className, byte[] classRep, int offset, int length, ProtectionDomain protectionDomain)323 protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length, 324 ProtectionDomain protectionDomain) throws java.lang.ClassFormatError { 325 326 return VMClassLoader.defineClass(this, className, classRep, offset, length, 327 protectionDomain); 328 } 329 330 /** 331 * Defines a new class with the specified name, byte code from the byte 332 * buffer and the optional protection domain. If the provided protection 333 * domain is {@code null} then a default protection domain is assigned to 334 * the class. 335 * 336 * @param name 337 * the expected name of the new class, may be {@code null} if not 338 * known. 339 * @param b 340 * the byte buffer containing the byte code of the new class. 341 * @param protectionDomain 342 * the protection domain to assign to the loaded class, may be 343 * {@code null}. 344 * @return the {@code Class} object created from the data in {@code b}. 345 * @throws ClassFormatError 346 * if {@code b} does not contain a valid class. 347 * @throws NoClassDefFoundError 348 * if {@code className} is not equal to the name of the class 349 * contained in {@code b}. 350 */ defineClass(String name, ByteBuffer b, ProtectionDomain protectionDomain)351 protected final Class<?> defineClass(String name, ByteBuffer b, 352 ProtectionDomain protectionDomain) throws ClassFormatError { 353 354 byte[] temp = new byte[b.remaining()]; 355 b.get(temp); 356 return defineClass(name, temp, 0, temp.length, protectionDomain); 357 } 358 359 /** 360 * Overridden by subclasses, throws a {@code ClassNotFoundException} by 361 * default. This method is called by {@code loadClass} after the parent 362 * {@code ClassLoader} has failed to find a loaded class of the same name. 363 * 364 * @param className 365 * the name of the class to look for. 366 * @return the {@code Class} object that is found. 367 * @throws ClassNotFoundException 368 * if the class cannot be found. 369 */ findClass(String className)370 protected Class<?> findClass(String className) throws ClassNotFoundException { 371 throw new ClassNotFoundException(className); 372 } 373 374 /** 375 * Returns the class with the specified name if it has already been loaded 376 * by the virtual machine or {@code null} if it has not yet been loaded. 377 * 378 * @param className 379 * the name of the class to look for. 380 * @return the {@code Class} object or {@code null} if the requested class 381 * has not been loaded. 382 */ findLoadedClass(String className)383 protected final Class<?> findLoadedClass(String className) { 384 ClassLoader loader; 385 if (this == BootClassLoader.getInstance()) 386 loader = null; 387 else 388 loader = this; 389 return VMClassLoader.findLoadedClass(loader, className); 390 } 391 392 /** 393 * Finds the class with the specified name, loading it using the system 394 * class loader if necessary. 395 * 396 * @param className 397 * the name of the class to look for. 398 * @return the {@code Class} object with the requested {@code className}. 399 * @throws ClassNotFoundException 400 * if the class can not be found. 401 */ findSystemClass(String className)402 protected final Class<?> findSystemClass(String className) throws ClassNotFoundException { 403 return Class.forName(className, false, getSystemClassLoader()); 404 } 405 406 /** 407 * Returns this class loader's parent. 408 * 409 * @return this class loader's parent or {@code null}. 410 * @throws SecurityException 411 * if a security manager exists and it does not allow to 412 * retrieve the parent class loader. 413 */ getParent()414 public final ClassLoader getParent() { 415 SecurityManager smgr = System.getSecurityManager(); 416 if (smgr != null) { 417 smgr.checkPermission(new RuntimePermission("getClassLoader")); 418 } 419 420 return parent; 421 } 422 423 /** 424 * Returns the URL of the resource with the specified name. This 425 * implementation first tries to use the parent class loader to find the 426 * resource; if this fails then {@link #findResource(String)} is called to 427 * find the requested resource. 428 * 429 * @param resName 430 * the name of the resource to find. 431 * @return the {@code URL} object for the requested resource or {@code null} 432 * if either the resource can not be found or a security manager 433 * does not allow to access the resource. 434 * @see Class#getResource 435 */ getResource(String resName)436 public URL getResource(String resName) { 437 URL resource = null; 438 439 resource = parent.getResource(resName); 440 441 if (resource == null) { 442 resource = findResource(resName); 443 } 444 445 return resource; 446 } 447 448 /** 449 * Returns an enumeration of URLs for the resource with the specified name. 450 * This implementation first uses this class loader's parent to find the 451 * resource, then it calls {@link #findResources(String)} to get additional 452 * URLs. The returned enumeration contains the {@code URL} objects of both 453 * find operations. 454 * 455 * @return an enumeration of {@code URL} objects for the requested resource. 456 * @param resName 457 * the name of the resource to find. 458 * @throws IOException 459 * if an I/O error occurs. 460 */ 461 @SuppressWarnings("unchecked") getResources(String resName)462 public Enumeration<URL> getResources(String resName) throws IOException { 463 464 Enumeration first = parent.getResources(resName); 465 Enumeration second = findResources(resName); 466 467 return new TwoEnumerationsInOne(first, second); 468 } 469 470 /** 471 * Returns a stream for the resource with the specified name. See 472 * {@link #getResource(String)} for a description of the lookup algorithm 473 * used to find the resource. 474 * 475 * @return a stream for the resource or {@code null} if either the resource 476 * can not be found or a security manager does not allow to access 477 * the resource. 478 * @param resName 479 * the name of the resource to find. 480 * @see Class#getResourceAsStream 481 */ getResourceAsStream(String resName)482 public InputStream getResourceAsStream(String resName) { 483 try { 484 URL url = getResource(resName); 485 if (url != null) { 486 return url.openStream(); 487 } 488 } catch (IOException ex) { 489 // Don't want to see the exception. 490 } 491 492 return null; 493 } 494 495 /** 496 * Loads the class with the specified name. Invoking this method is 497 * equivalent to calling {@code loadClass(className, false)}. 498 * <p> 499 * <strong>Note:</strong> In the Android reference implementation, the 500 * second parameter of {@link #loadClass(String, boolean)} is ignored 501 * anyway. 502 * </p> 503 * 504 * @return the {@code Class} object. 505 * @param className 506 * the name of the class to look for. 507 * @throws ClassNotFoundException 508 * if the class can not be found. 509 */ loadClass(String className)510 public Class<?> loadClass(String className) throws ClassNotFoundException { 511 return loadClass(className, false); 512 } 513 514 /** 515 * Loads the class with the specified name, optionally linking it after 516 * loading. The following steps are performed: 517 * <ol> 518 * <li> Call {@link #findLoadedClass(String)} to determine if the requested 519 * class has already been loaded.</li> 520 * <li>If the class has not yet been loaded: Invoke this method on the 521 * parent class loader.</li> 522 * <li>If the class has still not been loaded: Call 523 * {@link #findClass(String)} to find the class.</li> 524 * </ol> 525 * <p> 526 * <strong>Note:</strong> In the Android reference implementation, the 527 * {@code resolve} parameter is ignored; classes are never linked. 528 * </p> 529 * 530 * @return the {@code Class} object. 531 * @param className 532 * the name of the class to look for. 533 * @param resolve 534 * Indicates if the class should be resolved after loading. This 535 * parameter is ignored on the Android reference implementation; 536 * classes are not resolved. 537 * @throws ClassNotFoundException 538 * if the class can not be found. 539 */ loadClass(String className, boolean resolve)540 protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException { 541 Class<?> clazz = findLoadedClass(className); 542 543 if (clazz == null) { 544 try { 545 clazz = parent.loadClass(className, false); 546 } catch (ClassNotFoundException e) { 547 // Don't want to see this. 548 } 549 550 if (clazz == null) { 551 clazz = findClass(className); 552 } 553 } 554 555 return clazz; 556 } 557 558 /** 559 * Forces a class to be linked (initialized). If the class has already been 560 * linked this operation has no effect. 561 * <p> 562 * <strong>Note:</strong> In the Android reference implementation, this 563 * method has no effect. 564 * </p> 565 * 566 * @param clazz 567 * the class to link. 568 */ resolveClass(Class<?> clazz)569 protected final void resolveClass(Class<?> clazz) { 570 // no-op, doesn't make sense on android. 571 } 572 573 /** 574 * Indicates whether this class loader is the system class loader. This 575 * method must be provided by the virtual machine vendor, as it is used by 576 * other provided class implementations in this package. A sample 577 * implementation of this method is provided by the reference 578 * implementation. This method is used by 579 * SecurityManager.classLoaderDepth(), currentClassLoader() and 580 * currentLoadedClass(). Returns true if the receiver is a system class 581 * loader. 582 * <p> 583 * Note that this method has package visibility only. It is defined here to 584 * avoid the security manager check in getSystemClassLoader, which would be 585 * required to implement this method anywhere else. 586 * </p> 587 * 588 * @return {@code true} if the receiver is a system class loader 589 * @see Class#getClassLoaderImpl() 590 */ isSystemClassLoader()591 final boolean isSystemClassLoader() { 592 return false; 593 } 594 595 /** 596 * <p> 597 * Returns true if the receiver is ancestor of another class loader. It also 598 * returns true if the two class loader are equal. 599 * </p> 600 * <p> 601 * Note that this method has package visibility only. It is defined here to 602 * avoid the security manager check in getParent, which would be required to 603 * implement this method anywhere else. The method is also required in other 604 * places where class loaders are accesses. 605 * </p> 606 * 607 * @param child 608 * A child candidate 609 * @return {@code true} if the receiver is ancestor of, or equal to, 610 * the parameter 611 */ isAncestorOf(ClassLoader child)612 final boolean isAncestorOf(ClassLoader child) { 613 for (ClassLoader current = child; current != null; 614 current = current.parent) { 615 if (current == this) { 616 return true; 617 } 618 } 619 return false; 620 } 621 622 /** 623 * Finds the URL of the resource with the specified name. This 624 * implementation just returns {@code null}; it should be overridden in 625 * subclasses. 626 * 627 * @param resName 628 * the name of the resource to find. 629 * @return the {@code URL} object for the requested resource. 630 */ findResource(String resName)631 protected URL findResource(String resName) { 632 return null; 633 } 634 635 /** 636 * Finds an enumeration of URLs for the resource with the specified name. 637 * This implementation just returns an empty {@code Enumeration}; it should 638 * be overridden in subclasses. 639 * 640 * @param resName 641 * the name of the resource to find. 642 * @return an enumeration of {@code URL} objects for the requested resource. 643 * @throws IOException 644 * if an I/O error occurs. 645 */ 646 @SuppressWarnings( { 647 "unchecked", "unused" 648 }) findResources(String resName)649 protected Enumeration<URL> findResources(String resName) throws IOException { 650 return EmptyEnumeration.getInstance(); 651 } 652 653 /** 654 * Returns the absolute path of the native library with the specified name, 655 * or {@code null}. If this method returns {@code null} then the virtual 656 * machine searches the directories specified by the system property 657 * "java.library.path". 658 * <p> 659 * This implementation always returns {@code null}. 660 * </p> 661 * 662 * @param libName 663 * the name of the library to find. 664 * @return the absolute path of the library. 665 */ findLibrary(String libName)666 protected String findLibrary(String libName) { 667 return null; 668 } 669 670 /** 671 * Returns the package with the specified name. Package information is 672 * searched in this class loader. 673 * 674 * @param name 675 * the name of the package to find. 676 * @return the package with the requested name; {@code null} if the package 677 * can not be found. 678 */ getPackage(String name)679 protected Package getPackage(String name) { 680 synchronized (packages) { 681 Package p = packages.get(name); 682 return p; 683 } 684 } 685 686 /** 687 * Gets the package with the specified name, searching it in the specified 688 * class loader. 689 * 690 * @param loader 691 * the class loader to search the package in. 692 * @param name 693 * the name of the package to find. 694 * @return the package with the requested name; {@code null} if the package 695 * can not be found. 696 */ getPackage(ClassLoader loader, String name)697 static Package getPackage(ClassLoader loader, String name) { 698 return loader.getPackage(name); 699 } 700 701 /** 702 * Returns all the packages known to this class loader. 703 * 704 * @return an array with all packages known to this class loader. 705 */ getPackages()706 protected Package[] getPackages() { 707 synchronized (packages) { 708 Collection<Package> col = packages.values(); 709 Package[] result = new Package[col.size()]; 710 col.toArray(result); 711 return result; 712 } 713 } 714 715 /** 716 * Defines and returns a new {@code Package} using the specified 717 * information. If {@code sealBase} is {@code null}, the package is left 718 * unsealed. Otherwise, the package is sealed using this URL. 719 * 720 * @param name 721 * the name of the package. 722 * @param specTitle 723 * the title of the specification. 724 * @param specVersion 725 * the version of the specification. 726 * @param specVendor 727 * the vendor of the specification. 728 * @param implTitle 729 * the implementation title. 730 * @param implVersion 731 * the implementation version. 732 * @param implVendor 733 * the specification vendor. 734 * @param sealBase 735 * the URL used to seal this package or {@code null} to leave the 736 * package unsealed. 737 * @return the {@code Package} object that has been created. 738 * @throws IllegalArgumentException 739 * if a package with the specified name already exists. 740 */ definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase)741 protected Package definePackage(String name, String specTitle, String specVersion, 742 String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) 743 throws IllegalArgumentException { 744 745 synchronized (packages) { 746 if (packages.containsKey(name)) { 747 throw new IllegalArgumentException("Package " + name + " already defined"); 748 } 749 750 Package newPackage = new Package(name, specTitle, specVersion, specVendor, implTitle, 751 implVersion, implVendor, sealBase); 752 753 packages.put(name, newPackage); 754 755 return newPackage; 756 } 757 } 758 759 /** 760 * Gets the signers of the specified class. This implementation returns 761 * {@code null}. 762 * 763 * @param c 764 * the {@code Class} object for which to get the signers. 765 * @return signers the signers of {@code c}. 766 */ getSigners(Class<?> c)767 final Object[] getSigners(Class<?> c) { 768 return null; 769 } 770 771 /** 772 * Sets the signers of the specified class. This implementation does 773 * nothing. 774 * 775 * @param c 776 * the {@code Class} object for which to set the signers. 777 * @param signers 778 * the signers for {@code c}. 779 */ setSigners(Class<?> c, Object[] signers)780 protected final void setSigners(Class<?> c, Object[] signers) { 781 return; 782 } 783 784 /** 785 * <p> 786 * This must be provided by the VM vendor. It is used by 787 * SecurityManager.checkMemberAccess() with depth = 3. Note that 788 * checkMemberAccess() assumes the following stack when called:<br> 789 * </p> 790 * 791 * <pre> 792 * < user code &gt; <- want this class 793 * Class.getDeclared*(); 794 * Class.checkMemberAccess(); 795 * SecurityManager.checkMemberAccess(); <- current frame 796 * </pre> 797 * 798 * <p> 799 * Returns the ClassLoader of the method (including natives) at the 800 * specified depth on the stack of the calling thread. Frames representing 801 * the VM implementation of java.lang.reflect are not included in the list. 802 * </p> 803 * Notes: 804 * <ul> 805 * <li>This method operates on the defining classes of methods on stack. 806 * NOT the classes of receivers.</li> 807 * <li>The item at depth zero is the caller of this method</li> 808 * </ul> 809 * 810 * @param depth 811 * the stack depth of the requested ClassLoader 812 * @return the ClassLoader at the specified depth 813 */ getStackClassLoader(int depth)814 static final ClassLoader getStackClassLoader(int depth) { 815 Class<?>[] stack = VMStack.getClasses(depth + 1, false); 816 if(stack.length < depth + 1) { 817 return null; 818 } 819 return stack[depth].getClassLoader(); 820 } 821 822 /** 823 * This method must be provided by the VM vendor, as it is called by 824 * java.lang.System.loadLibrary(). System.loadLibrary() cannot call 825 * Runtime.loadLibrary() because this method loads the library using the 826 * ClassLoader of the calling method. Loads and links the library specified 827 * by the argument. 828 * 829 * @param libName 830 * the name of the library to load 831 * @param loader 832 * the classloader in which to load the library 833 * @throws UnsatisfiedLinkError 834 * if the library could not be loaded 835 * @throws SecurityException 836 * if the library was not allowed to be loaded 837 * <p> 838 * <strong>Note: </strong>This method does nothing in the Android reference 839 * implementation. 840 * </p> 841 */ loadLibraryWithClassLoader(String libName, ClassLoader loader)842 static void loadLibraryWithClassLoader(String libName, ClassLoader loader) { 843 return; 844 } 845 846 /** 847 * This method must be provided by the VM vendor, as it is called by 848 * java.lang.System.load(). System.load() cannot call Runtime.load() because 849 * the library is loaded using the ClassLoader of the calling method. Loads 850 * and links the library specified by the argument. No security check is 851 * done. 852 * <p> 853 * <strong>Note: </strong>This method does nothing in the Android reference 854 * implementation. 855 * </p> 856 * 857 * @param libName 858 * the name of the library to load 859 * @param loader 860 * the classloader in which to load the library 861 * @param libraryPath 862 * the library path to search, or null 863 * @throws UnsatisfiedLinkError 864 * if the library could not be loaded 865 */ loadLibraryWithPath(String libName, ClassLoader loader, String libraryPath)866 static void loadLibraryWithPath(String libName, ClassLoader loader, String libraryPath) { 867 return; 868 } 869 870 /** 871 * Sets the assertion status of the class with the specified name. 872 * <p> 873 * <strong>Note: </strong>This method does nothing in the Android reference 874 * implementation. 875 * </p> 876 * 877 * @param cname 878 * the name of the class for which to set the assertion status. 879 * @param enable 880 * the new assertion status. 881 */ setClassAssertionStatus(String cname, boolean enable)882 public void setClassAssertionStatus(String cname, boolean enable) { 883 return; 884 } 885 886 /** 887 * Sets the assertion status of the package with the specified name. 888 * <p> 889 * <strong>Note: </strong>This method does nothing in the Android reference 890 * implementation. 891 * </p> 892 * 893 * @param pname 894 * the name of the package for which to set the assertion status. 895 * @param enable 896 * the new assertion status. 897 */ setPackageAssertionStatus(String pname, boolean enable)898 public void setPackageAssertionStatus(String pname, boolean enable) { 899 return; 900 } 901 902 /** 903 * Sets the default assertion status for this class loader. 904 * <p> 905 * <strong>Note: </strong>This method does nothing in the Android reference 906 * implementation. 907 * </p> 908 * 909 * @param enable 910 * the new assertion status. 911 */ setDefaultAssertionStatus(boolean enable)912 public void setDefaultAssertionStatus(boolean enable) { 913 return; 914 } 915 916 /** 917 * Sets the default assertion status for this class loader to {@code false} 918 * and removes any package default and class assertion status settings. 919 * <p> 920 * <strong>Note:</strong> This method does nothing in the Android reference 921 * implementation. 922 * </p> 923 */ clearAssertionStatus()924 public void clearAssertionStatus() { 925 return; 926 } 927 928 /** 929 * Returns the assertion status of the named class Returns the assertion 930 * status of the class or nested class if it has been set. Otherwise returns 931 * the assertion status of its package or superpackage if that has been set. 932 * Otherwise returns the default assertion status. Returns 1 for enabled and 933 * 0 for disabled. 934 * 935 * @return the assertion status. 936 * @param cname 937 * the name of class. 938 */ getClassAssertionStatus(String cname)939 boolean getClassAssertionStatus(String cname) { 940 return false; 941 } 942 943 /** 944 * Returns the assertion status of the named package Returns the assertion 945 * status of the named package or superpackage if that has been set. 946 * Otherwise returns the default assertion status. Returns 1 for enabled and 947 * 0 for disabled. 948 * 949 * @return the assertion status. 950 * @param pname 951 * the name of package. 952 */ getPackageAssertionStatus(String pname)953 boolean getPackageAssertionStatus(String pname) { 954 return false; 955 } 956 957 /** 958 * Returns the default assertion status 959 * 960 * @return the default assertion status. 961 */ getDefaultAssertionStatus()962 boolean getDefaultAssertionStatus() { 963 return false; 964 } 965 } 966 967 /* 968 * Provides a helper class that combines two existing URL enumerations into one. 969 * It is required for the getResources() methods. Items are fetched from the 970 * first enumeration until it's empty, then from the second one. 971 */ 972 class TwoEnumerationsInOne implements Enumeration<URL> { 973 974 private Enumeration<URL> first; 975 976 private Enumeration<URL> second; 977 TwoEnumerationsInOne(Enumeration<URL> first, Enumeration<URL> second)978 public TwoEnumerationsInOne(Enumeration<URL> first, Enumeration<URL> second) { 979 this.first = first; 980 this.second = second; 981 } 982 hasMoreElements()983 public boolean hasMoreElements() { 984 return first.hasMoreElements() || second.hasMoreElements(); 985 } 986 nextElement()987 public URL nextElement() { 988 if (first.hasMoreElements()) { 989 return first.nextElement(); 990 } else { 991 return second.nextElement(); 992 } 993 } 994 995 } 996 997 /** 998 * Provides an explicit representation of the boot class loader. It sits at the 999 * head of the class loader chain and delegates requests to the VM's internal 1000 * class loading mechanism. 1001 */ 1002 class BootClassLoader extends ClassLoader { 1003 1004 static BootClassLoader instance; 1005 getInstance()1006 public static synchronized BootClassLoader getInstance() { 1007 if (instance == null) { 1008 instance = new BootClassLoader(); 1009 } 1010 1011 return instance; 1012 } 1013 BootClassLoader()1014 public BootClassLoader() { 1015 super(null, true); 1016 } 1017 1018 @Override findClass(String name)1019 protected Class<?> findClass(String name) throws ClassNotFoundException { 1020 return VMClassLoader.loadClass(name, false); 1021 } 1022 1023 @Override findResource(String name)1024 protected URL findResource(String name) { 1025 return VMClassLoader.getResource(name); 1026 } 1027 1028 @SuppressWarnings("unused") 1029 @Override findResources(String resName)1030 protected Enumeration<URL> findResources(String resName) throws IOException { 1031 Enumeration<URL> result = VMClassLoader.getResources(resName); 1032 1033 // VMClassLoader doesn't keep the contract for getResources() 1034 if (result == null) { 1035 result = EmptyEnumeration.getInstance(); 1036 } 1037 1038 return result; 1039 } 1040 1041 /** 1042 * Returns package information for the given package. Unfortunately, the 1043 * Android BootClassLoader doesn't really have this information, and as a 1044 * non-secure ClassLoader, it isn't even required to, according to the spec. 1045 * Yet, we want to provide it, in order to make all those hopeful callers of 1046 * {@code myClass.getPackage().getName()} happy. Thus we construct a Package 1047 * object the first time it is being requested and fill most of the fields 1048 * with dummy values. The Package object is then put into the ClassLoader's 1049 * Package cache, so we see the same one next time. We don't create Package 1050 * objects for null arguments or for the default package. 1051 * <p> 1052 * There a limited chance that we end up with multiple Package objects 1053 * representing the same package: It can happen when when a package is 1054 * scattered across different JAR files being loaded by different 1055 * ClassLoaders. Rather unlikely, and given that this whole thing is more or 1056 * less a workaround, probably not worth the effort. 1057 */ 1058 @Override getPackage(String name)1059 protected Package getPackage(String name) { 1060 if (name != null && !name.isEmpty()) { 1061 synchronized (this) { 1062 Package pack = super.getPackage(name); 1063 1064 if (pack == null) { 1065 pack = definePackage(name, "Unknown", "0.0", "Unknown", "Unknown", "0.0", 1066 "Unknown", null); 1067 } 1068 1069 return pack; 1070 } 1071 } 1072 1073 return null; 1074 } 1075 1076 @Override getResource(String resName)1077 public URL getResource(String resName) { 1078 return findResource(resName); 1079 } 1080 1081 @Override loadClass(String className, boolean resolve)1082 protected Class<?> loadClass(String className, boolean resolve) 1083 throws ClassNotFoundException { 1084 Class<?> clazz = findLoadedClass(className); 1085 1086 if (clazz == null) { 1087 clazz = findClass(className); 1088 } 1089 1090 return clazz; 1091 } 1092 1093 @Override getResources(String resName)1094 public Enumeration<URL> getResources(String resName) throws IOException { 1095 return findResources(resName); 1096 } 1097 } 1098 1099 /** 1100 * TODO Open issues - Missing / empty methods - Signer stuff - Protection 1101 * domains - Assertions 1102 */ 1103