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