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 java.io.IOException; 36 import java.io.InputStream; 37 import java.net.URL; 38 import java.nio.ByteBuffer; 39 import java.security.ProtectionDomain; 40 import java.util.Collection; 41 import java.util.Enumeration; 42 import java.util.Map; 43 import java.util.HashMap; 44 45 import dalvik.system.PathClassLoader; 46 import 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 */ 67 public 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 */ createSystemClassLoader()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 */ getSystemClassLoader()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 */ getSystemResource(String resName)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 */ getSystemResources(String resName)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 */ getSystemResourceAsStream(String resName)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 */ ClassLoader()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 */ ClassLoader(ClassLoader parentLoader)225 protected ClassLoader(ClassLoader parentLoader) { 226 this(parentLoader, false); 227 } 228 229 /* 230 * constructor for the BootClassLoader which needs parent to be null. 231 */ ClassLoader(ClassLoader parentLoader, boolean nullAllowed)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 defineClass(byte[] classRep, int offset, int length)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 */ defineClass(String className, byte[] classRep, int offset, int length)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 */ defineClass(String className, byte[] classRep, int offset, int length, ProtectionDomain protectionDomain)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 */ defineClass(String name, ByteBuffer b, ProtectionDomain protectionDomain)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 */ findClass(String className)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 */ findLoadedClass(String className)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 */ findSystemClass(String className)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 */ getParent()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 */ getResource(String resName)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") getResources(String resName)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 */ getResourceAsStream(String resName)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 */ loadClass(String className)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 */ loadClass(String className, boolean resolve)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 */ resolveClass(Class<?> clazz)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 */ isSystemClassLoader()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 */ isAncestorOf(ClassLoader child)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 */ findResource(String resName)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 }) findResources(String resName)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 */ findLibrary(String libName)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 */ getPackage(String name)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 */ getPackage(ClassLoader loader, String name)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 */ getPackages()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 */ definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase)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 */ getSigners(Class<?> c)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 */ setSigners(Class<?> c, Object[] signers)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 */ getStackClassLoader(int depth)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 */ loadLibraryWithClassLoader(String libName, ClassLoader loader)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 */ loadLibraryWithPath(String libName, ClassLoader loader, String libraryPath)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 */ setClassAssertionStatus(String cname, boolean enable)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 */ setPackageAssertionStatus(String pname, boolean enable)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 */ setDefaultAssertionStatus(boolean enable)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 */ clearAssertionStatus()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 */ getClassAssertionStatus(String cname)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 */ getPackageAssertionStatus(String pname)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 */ getDefaultAssertionStatus()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 */ 1009 class TwoEnumerationsInOne implements Enumeration<URL> { 1010 1011 private Enumeration<URL> first; 1012 1013 private Enumeration<URL> second; 1014 TwoEnumerationsInOne(Enumeration<URL> first, Enumeration<URL> second)1015 public TwoEnumerationsInOne(Enumeration<URL> first, Enumeration<URL> second) { 1016 this.first = first; 1017 this.second = second; 1018 } 1019 hasMoreElements()1020 public boolean hasMoreElements() { 1021 return first.hasMoreElements() || second.hasMoreElements(); 1022 } 1023 nextElement()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 */ 1039 class BootClassLoader extends ClassLoader { 1040 1041 static BootClassLoader instance; 1042 getInstance()1043 public static BootClassLoader getInstance() { 1044 if (instance == null) { 1045 instance = new BootClassLoader(); 1046 } 1047 1048 return instance; 1049 } 1050 BootClassLoader()1051 public BootClassLoader() { 1052 super(null, true); 1053 } 1054 1055 @Override findClass(String name)1056 protected Class<?> findClass(String name) throws ClassNotFoundException { 1057 return VMClassLoader.loadClass(name, false); 1058 } 1059 1060 @Override findResource(String name)1061 protected URL findResource(String name) { 1062 return VMClassLoader.getResource(name); 1063 } 1064 1065 @SuppressWarnings("unused") 1066 @Override findResources(String resName)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 getPackage(String name)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 getResource(String resName)1114 public URL getResource(String resName) { 1115 return findResource(resName); 1116 } 1117 1118 @Override loadClass(String className, boolean resolve)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 getResources(String resName)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