1. /*
  2. * @(#)ClassLoader.java 1.131 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.lang;
  8. import java.io.InputStream;
  9. import java.io.IOException;
  10. import java.io.StringWriter;
  11. import java.io.PrintWriter;
  12. import java.io.File;
  13. import java.util.Hashtable;
  14. import java.util.Enumeration;
  15. import java.util.Vector;
  16. import java.util.Stack;
  17. import java.util.HashMap;
  18. import java.util.HashSet;
  19. import java.util.Map;
  20. import java.util.NoSuchElementException;
  21. import java.util.Set;
  22. import java.util.jar.Manifest;
  23. import java.net.URL;
  24. import java.net.MalformedURLException;
  25. import java.security.AccessController;
  26. import java.security.AccessControlContext;
  27. import java.security.PrivilegedAction;
  28. import java.security.ProtectionDomain;
  29. import java.security.PermissionCollection;
  30. import java.security.CodeSource;
  31. import java.security.Policy;
  32. import sun.misc.URLClassPath;
  33. import sun.misc.Resource;
  34. import sun.misc.CompoundEnumeration;
  35. //import sun.misc.Launcher;
  36. /**
  37. * The class <code>ClassLoader</code> is an abstract class.
  38. * A class loader is an object that is responsible for loading
  39. * classes. Given the name of a class, it should attempt to locate
  40. * or generate data that constitutes a definition for the class. A
  41. * typical strategy is to transform the name into a file
  42. * name and then read a "class file" of that name from a file system.
  43. * <p>
  44. * Every <code>Class</code> object contains a
  45. * {@link Class#getClassLoader() reference} to the
  46. * <code>ClassLoader</code> that defined it.
  47. * <p>
  48. * Class objects for array classes are not created by class loaders, but
  49. * are created automatically as required by the Java runtime. The class
  50. * loader for an array class, as returned by {@link Class#getClassLoader()}
  51. * is the same as the class loader for its element type; if the element
  52. * type is a primitive type, then the array class has no class loader.
  53. * <p>
  54. * Applications implement subclasses of <code>ClassLoader</code> in
  55. * order to extend the manner in which the Java virtual machine
  56. * dynamically loads classes.
  57. * <p>
  58. * Class loaders may typically be used by security managers to
  59. * indicate security domains.
  60. * <p>
  61. * The <code>ClassLoader</code> class uses a delegation model to
  62. * search for classes and resources. Each instance of
  63. * <code>ClassLoader</code> has an associated parent class loader.
  64. * When called upon to find a class or resource, a
  65. * <code>ClassLoader</code> instance will delegate the search for
  66. * the class or resource to its parent class loader before
  67. * attempting to find the class or resource itself. The virtual
  68. * machine's built-in class loader, called the bootstrap class loader,
  69. * does not itself have a parent but may serve as the parent of a
  70. * <code>ClassLoader</code> instance.
  71. * <p>
  72. * Normally, the Java virtual machine loads classes from the local
  73. * file system in a platform-dependent manner. For example, on UNIX
  74. * systems, the virtual machine loads classes from the directory
  75. * defined by the <code>CLASSPATH</code> environment variable.
  76. * <p>
  77. * However, some classes may not originate from a file; they may
  78. * originate from other sources, such as the network, or they could
  79. * be constructed by an application. The method
  80. * <code>defineClass</code> converts an array of bytes into an
  81. * instance of class <code>Class</code>. Instances of this newly
  82. * defined class can be created using the <code>newInstance</code>
  83. * method in class <code>Class</code>.
  84. * <p>
  85. * The methods and constructors of objects created by a class loader
  86. * may reference other classes. To determine the class(es) referred
  87. * to, the Java virtual machine calls the <code>loadClass</code>
  88. * method of the class loader that originally created the class.
  89. * <p>
  90. * For example, an application could create a network class loader
  91. * to download class files from a server. Sample code might look like:
  92. * <blockquote><pre>
  93. * ClassLoader loader = new NetworkClassLoader(host, port);
  94. * Object main = loader.loadClass("Main", true).newInstance();
  95. *  . . .
  96. * </pre></blockquote>
  97. * <p>
  98. * The network class loader subclass must define the methods
  99. * <code>findClass</code> and <code>loadClassData</code>
  100. * to load a class from the network. Once it
  101. * has downloaded the bytes that make up the class, it should use the
  102. * method <code>defineClass</code> to create a class instance. A
  103. * sample implementation is:
  104. * <p><hr><blockquote><pre>
  105. * class NetworkClassLoader extends ClassLoader {
  106. * String host;
  107. * int port;
  108. *
  109. * public Class findClass(String name) {
  110. * byte[] b = loadClassData(name);
  111. * return defineClass(name, b, 0, b.length);
  112. * }
  113. *
  114. * private byte[] loadClassData(String name) {
  115. * // load the class data from the connection
  116. *  . . .
  117. * }
  118. * }
  119. * </pre></blockquote><hr>
  120. *
  121. * @version 1.131, 11/29/01
  122. * @see java.lang.Class
  123. * @see java.lang.Class#newInstance()
  124. * @see java.lang.ClassLoader#defineClass(byte[], int, int)
  125. * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
  126. * @see java.lang.ClassLoader#resolveClass(java.lang.Class)
  127. * @since JDK1.0
  128. */
  129. public abstract class ClassLoader {
  130. /*
  131. * If initialization succeed this is set to true and security checks will
  132. * succeed. Otherwise the object is not initialized and the object is
  133. * useless.
  134. */
  135. private boolean initialized = false;
  136. /*
  137. * The parent class loader for delegation.
  138. */
  139. private ClassLoader parent;
  140. /*
  141. * Hashtable that maps packages to certs
  142. */
  143. private Hashtable package2certs = new Hashtable(11);
  144. /*
  145. * shared among all packages with unsigned classes
  146. */
  147. java.security.cert.Certificate[] nocerts;
  148. /*
  149. * The classes loaded by this class loader. The only purpose of this
  150. * table is to keep the classes from being GC'ed until the loader
  151. * is GC'ed.
  152. */
  153. private Vector classes = new Vector();
  154. /*
  155. * The initiating protection domains for all classes
  156. * loaded by this loader.
  157. */
  158. private Set domains = new HashSet();
  159. /*
  160. * Called by the VM to record every loaded class with this loader.
  161. */
  162. void addClass(Class c) {
  163. classes.addElement(c);
  164. }
  165. /*
  166. * The packages defined in this class loader. Each package name is
  167. * mapped to its corresponding Package object.
  168. */
  169. private HashMap packages = new HashMap();
  170. /**
  171. * Creates a new class loader using the specified parent class loader
  172. * for delegation.
  173. * <p>
  174. * If there is a security manager, its <code>checkCreateClassLoader</code>
  175. * method is called. This may result in a security exception.
  176. *
  177. * @throws SecurityException
  178. * if a security manager exists and its <code>checkCreateClassLoader</code>
  179. * method doesn't allow creation of a new class loader.
  180. *
  181. * @see java.lang.SecurityException
  182. * @see java.lang.SecurityManager#checkCreateClassLoader()
  183. * @since JDK1.2
  184. */
  185. protected ClassLoader(ClassLoader parent) {
  186. SecurityManager security = System.getSecurityManager();
  187. if (security != null) {
  188. security.checkCreateClassLoader();
  189. }
  190. this.parent = parent;
  191. initialized = true;
  192. }
  193. /**
  194. * Creates a new class loader using the <code>ClassLoader</code>
  195. * returned by the method <code>getSystemClassLoader()</code> as the
  196. * parent class loader.
  197. * <p>
  198. * This constructor is invoked for every newly created class loader.
  199. * Because the class <code>ClassLoader</code> is abstract, it is not
  200. * possible to create a new instance of the class <code>ClassLoader</code>
  201. * itself; however, every constructor for a subclass of
  202. * <code>ClassLoader</code> necessarily invokes this constructor,
  203. * explicitly or implicitly, directly or indirectly.
  204. * <p>
  205. * If there is a security manager, its <code>checkCreateClassLoader</code>
  206. * method is called. This may result in a security exception.
  207. *
  208. * @throws SecurityException
  209. * if a security manager exists and its <code>checkCreateClassLoader</code>
  210. * method doesn't allow creation of a new class loader.
  211. *
  212. * @see java.lang.SecurityException
  213. * @see java.lang.SecurityManager#checkCreateClassLoader()
  214. */
  215. protected ClassLoader() {
  216. SecurityManager security = System.getSecurityManager();
  217. if (security != null) {
  218. security.checkCreateClassLoader();
  219. }
  220. this.parent = getSystemClassLoader();
  221. initialized = true;
  222. }
  223. /**
  224. * Loads the class with the specified name. This method searches for
  225. * classes in the same manner as the {@link #loadClass(String, boolean)}
  226. * method. It is called by the Java virtual machine to resolve class
  227. * references. Calling this method is equivalent to calling
  228. * <code>loadClass(name, false)</code>.
  229. *
  230. * @param name the name of the class
  231. * @return the resulting <code>Class</code> object
  232. * @exception ClassNotFoundException if the class was not found
  233. */
  234. public Class loadClass(String name) throws ClassNotFoundException
  235. {
  236. return loadClass(name, false);
  237. }
  238. /**
  239. * Loads the class with the specified name. The default implementation of
  240. * this method searches for classes in the following order:<p>
  241. *
  242. * <ol>
  243. * <li> Call {@link #findLoadedClass(String)} to check if the class has
  244. * already been loaded. <p>
  245. * <li> Call the <code>loadClass</code> method on the parent class
  246. * loader. If the parent is <code>null</code> the class loader
  247. * built-in to the virtual machine is used, instead. <p>
  248. * <li> Call the {@link #findClass(String)} method to find the class. <p>
  249. * </ol>
  250. *
  251. * If the class was found using the above steps, and the
  252. * <code>resolve</code> flag is true, this method will then call the
  253. * {@link #resolveClass(Class)} method on the resulting class object.
  254. * <p>
  255. * From JDK1.2, subclasses of ClassLoader are encouraged to override
  256. * {@link #findClass(String)}, rather than this method.<p>
  257. *
  258. * @param name the name of the class
  259. * @param resolve if <code>true</code> then resolve the class
  260. * @return the resulting <code>Class</code> object
  261. * @exception ClassNotFoundException if the class could not be found
  262. */
  263. protected synchronized Class loadClass(String name, boolean resolve)
  264. throws ClassNotFoundException
  265. {
  266. // First, check if the class has already been loaded
  267. Class c = findLoadedClass(name);
  268. if (c == null) {
  269. try {
  270. if (parent != null) {
  271. c = parent.loadClass(name, false);
  272. } else {
  273. c = findBootstrapClass0(name);
  274. }
  275. } catch (ClassNotFoundException e) {
  276. // If still not found, then call findClass in order
  277. // to find the class.
  278. c = findClass(name);
  279. }
  280. }
  281. if (resolve) {
  282. resolveClass(c);
  283. }
  284. return c;
  285. }
  286. /*
  287. * This method is called by the virtual machine to load
  288. * a class.
  289. */
  290. private synchronized Class loadClassInternal(String name)
  291. throws ClassNotFoundException {
  292. return loadClass(name);
  293. }
  294. private void checkPackageAccess(Class cls, ProtectionDomain pd) {
  295. final SecurityManager sm = System.getSecurityManager();
  296. if (sm != null) {
  297. final String name = cls.getName();
  298. final int i = name.lastIndexOf('.');
  299. if (i != -1) {
  300. AccessController.doPrivileged(new PrivilegedAction() {
  301. public Object run() {
  302. sm.checkPackageAccess(name.substring(0, i));
  303. return null;
  304. }
  305. }, new AccessControlContext(new ProtectionDomain[] {pd}));
  306. }
  307. }
  308. domains.add(pd);
  309. }
  310. /**
  311. * Finds the specified class. This method should be overridden
  312. * by class loader implementations that follow the new delegation model
  313. * for loading classes, and will be called by the <code>loadClass</code>
  314. * method after checking the parent class loader for the requested class.
  315. * The default implementation throws <code>ClassNotFoundException</code>.
  316. *
  317. * @param name the name of the class
  318. * @return the resulting <code>Class</code> object
  319. * @exception ClassNotFoundException if the class could not be found
  320. * @since JDK1.2
  321. */
  322. protected Class findClass(String name) throws ClassNotFoundException {
  323. throw new ClassNotFoundException(name);
  324. }
  325. /**
  326. * Converts an array of bytes into an instance of class
  327. * <code>Class</code>. Before the Class can be used it must be
  328. * resolved. This method is deprecated in favor of the version
  329. * that takes the class name as its first argument, and is more
  330. * secure.
  331. *
  332. * @param b the bytes that make up the class data. The bytes in
  333. * positions <code>off</code> through <code>off+len-1</code>
  334. * should have the format of a valid class file as defined
  335. * by the
  336. * <a href="http://java.sun.com/docs/books/vmspec/">Java
  337. * Virtual Machine Specification</a>.
  338. * @param off the start offset of the class data
  339. * @param len the length of the class data
  340. * @return the <code>Class</code> object that was created from the
  341. * specified class data
  342. * @exception ClassFormatError if the data did not contain a valid class
  343. * @see ClassLoader#loadClass(java.lang.String, boolean)
  344. * @see ClassLoader#resolveClass(java.lang.Class)
  345. * @deprecated Replaced by defineClass(java.lang.String, byte[], int, int)
  346. */
  347. protected final Class defineClass(byte[] b, int off, int len)
  348. throws ClassFormatError
  349. {
  350. return defineClass(null, b, off, len, null);
  351. }
  352. /**
  353. * Converts an array of bytes into an instance of class <code>Class</code>.
  354. * Before the Class can be used it must be resolved.
  355. * <p>
  356. * This method assigns a default <code>ProtectionDomain</code> to
  357. * the newly defined class. The <code>ProtectionDomain</code>
  358. * contains the set of permissions granted when
  359. * a call to <code>Policy.getPolicy().getPermissions()</code> is made with
  360. * a Codesource of <code>null,null</code>. The default domain is
  361. * created on the first invocation of <code>defineClass</code>, and
  362. * re-used on subsequent calls.
  363. * <p>
  364. * To assign a specific <code>ProtectionDomain</code> to the class,
  365. * use the <code>defineClass</code> method that takes a
  366. * <code>ProtectionDomain</code> as one of its arguments.
  367. *
  368. * @param name the expected name of the class, or <code>null</code>
  369. * if not known, using '.' and not '/' as the separator
  370. * and without a trailing ".class" suffix.
  371. * @param b the bytes that make up the class data. The bytes in
  372. * positions <code>off</code> through <code>off+len-1</code>
  373. * should have the format of a valid class file as defined
  374. * by the
  375. * <a href="http://java.sun.com/docs/books/vmspec/">Java
  376. * Virtual Machine Specification</a>.
  377. * @param off the start offset of the class data
  378. * @param len the length of the class data
  379. * @return the <code>Class</code> object that was created from the
  380. * specified class data
  381. * @exception ClassFormatError if the data did not contain a valid class
  382. * @exception IndexOutOfBoundsException if either <code>off</code> or
  383. * <code>len</code> is negative, or if
  384. * <code>off+len</code> is greater than <code>b.length</code>.
  385. * @exception SecurityException if an attempt is made to add this class
  386. * to a package that contains classes that were signed by
  387. * a different set of certificates then this class, which
  388. * is unsigned.
  389. *
  390. * @see ClassLoader#loadClass(java.lang.String, boolean)
  391. * @see ClassLoader#resolveClass(java.lang.Class)
  392. * @see java.security.ProtectionDomain
  393. * @see java.security.Policy
  394. * @see java.security.CodeSource
  395. * @see java.security.SecureClassLoader
  396. * @since JDK1.1
  397. */
  398. protected final Class defineClass(String name, byte[] b, int off, int len)
  399. throws ClassFormatError
  400. {
  401. return defineClass(name, b, off, len, null);
  402. }
  403. /**
  404. * Converts an array of bytes into an instance of class Class,
  405. * with an optional ProtectionDomain. If the domain is <code>null</code>,
  406. * then a default domain will be assigned to the class as specified
  407. * in the documentation for {@link #defineClass(String,byte[],int,int)}.
  408. * Before the class can be used it must be resolved.
  409. *
  410. * <p>The first class defined in a package determines the exact set of
  411. * certificates that all subsequent classes defined in that package must
  412. * contain. The set of certificates for a class is obtained from the
  413. * <code>CodeSource</code> within the <code>ProtectionDomain</code> of
  414. * the class. Any classes added to that package must contain
  415. * the same set of certificates or a <code>SecurityException</code>
  416. * will be thrown. Note that if the <code>name</code> argument is
  417. * null, this check is not performed. You should always pass in the
  418. * name of the class you are defining as well as the bytes. This
  419. * ensures that the class you are defining is indeed the class
  420. * you think it is.
  421. *
  422. * @exception ClassFormatError if the data did not contain a valid class
  423. * @exception IndexOutOfBoundsException if either <code>off</code> or
  424. * <code>len</code> is negative, or if
  425. * <code>off+len</code> is greater than <code>b.length</code>.
  426. *
  427. * @exception SecurityException if an attempt is made to add this class
  428. * to a package that contains classes that were signed by
  429. * a different set of certificates then this class.
  430. *
  431. * @param name the name of the class
  432. * @param b the class bytes
  433. * @param off the start offset of the class bytes
  434. * @param len the length of the class bytes
  435. * @param protectionDomain the ProtectionDomain of the class
  436. * @return the <code>Class</code> object created from the data,
  437. * and optional ProtectionDomain.
  438. */
  439. protected final Class defineClass(String name, byte[] b, int off, int len,
  440. ProtectionDomain protectionDomain)
  441. throws ClassFormatError
  442. {
  443. check();
  444. if (protectionDomain == null) {
  445. protectionDomain = getDefaultDomain();
  446. }
  447. if (name != null)
  448. checkCerts(name, protectionDomain.getCodeSource());
  449. Class c = defineClass0(name, b, off, len, protectionDomain);
  450. if (protectionDomain.getCodeSource() != null) {
  451. java.security.cert.Certificate certs[] =
  452. protectionDomain.getCodeSource().getCertificates();
  453. if (certs != null)
  454. setSigners(c, certs);
  455. }
  456. return c;
  457. }
  458. private synchronized void checkCerts(String name, CodeSource cs)
  459. {
  460. int i = name.lastIndexOf('.');
  461. String pname = (i == -1) ? "" : name.substring(0,i);
  462. java.security.cert.Certificate[] pcerts =
  463. (java.security.cert.Certificate[]) package2certs.get(pname);
  464. if (pcerts == null) {
  465. // first class in this package gets to define which
  466. // certificates must be the same for all other classes
  467. // in this package
  468. if (cs != null) {
  469. pcerts = cs.getCertificates();
  470. }
  471. if (pcerts == null) {
  472. if (nocerts == null)
  473. nocerts = new java.security.cert.Certificate[0];
  474. pcerts = nocerts;
  475. }
  476. package2certs.put(pname, pcerts);
  477. } else {
  478. java.security.cert.Certificate[] certs = null;
  479. if (cs != null) {
  480. certs = cs.getCertificates();
  481. }
  482. if (!compareCerts(pcerts,certs)) {
  483. throw new SecurityException("class \""+ name+
  484. "\"'s signer information does not match signer information of other classes in the same package");
  485. }
  486. }
  487. }
  488. /**
  489. * check to make sure the certs for the new class (certs) are
  490. * the same as the certs for the first class inserted
  491. * in the package (pcerts)
  492. */
  493. private boolean compareCerts(java.security.cert.Certificate[] pcerts,
  494. java.security.cert.Certificate[] certs)
  495. {
  496. // certs can be null, indicating no certs.
  497. if ((certs == null) || (certs.length == 0)) {
  498. return pcerts.length == 0;
  499. }
  500. // the length must be the same at this point
  501. if (certs.length != pcerts.length)
  502. return false;
  503. // go through and make sure all the certs in one array
  504. // are in the other and vice-versa.
  505. boolean match;
  506. for (int i=0; i < certs.length; i++) {
  507. match = false;
  508. for (int j=0; j < pcerts.length; j++) {
  509. if (certs[i].equals(pcerts[j])) {
  510. match = true;
  511. break;
  512. }
  513. }
  514. if (!match) return false;
  515. }
  516. // now do the same for pcerts
  517. for (int i=0; i < pcerts.length; i++) {
  518. match = false;
  519. for (int j=0; j < certs.length; j++) {
  520. if (pcerts[i].equals(certs[j])) {
  521. match = true;
  522. break;
  523. }
  524. }
  525. if (!match) return false;
  526. }
  527. return true;
  528. }
  529. /**
  530. * Links the specified class.
  531. * This (misleadingly named) method may be used by a class loader to
  532. * link a class. If the class <code>c</code> has already been linked,
  533. * then this method simply returns. Otherwise, the class is linked
  534. * as described in the "Execution" chapter of the <i>Java Language
  535. * Specification</i>.
  536. *
  537. * @param c the class to link
  538. * @exception NullPointerException if <code>c</code> is <code>null</code>.
  539. * @see java.lang.ClassLoader#defineClass(java.lang.String,byte[],int,int)
  540. */
  541. protected final void resolveClass(Class c) {
  542. check();
  543. resolveClass0(c);
  544. }
  545. /**
  546. * Finds a class with the specified name, loading it if necessary.<p>
  547. *
  548. * Prior to JDK1.2, this method loads a class from the local file
  549. * system in a platform-dependent manner, and returns a class object
  550. * that has no associated class loader.<p>
  551. *
  552. * Since JDK1.2, this method loads the class through the system class
  553. * loader(see {@link #getSystemClassLoader()}). Class objects returned
  554. * might have <code>ClassLoader</code>s associated with them. Subclasses
  555. * of <code>ClassLoader</code> need not usually call this method, because
  556. * most class loaders need to override just {@link #findClass(String)}.<p>
  557. *
  558. * @see #ClassLoader(ClassLoader)
  559. * @see #getParent()
  560. * @param name the name of the class that is to be found
  561. * @return a system class with the given name
  562. * @exception ClassNotFoundException if the class could not be found
  563. */
  564. protected final Class findSystemClass(String name)
  565. throws ClassNotFoundException
  566. {
  567. check();
  568. ClassLoader system = getSystemClassLoader();
  569. if (system == null) {
  570. return findBootstrapClass(name);
  571. }
  572. return system.loadClass(name);
  573. }
  574. /**
  575. * Returns the parent class loader for delegation. Some implementations
  576. * may use <code>null</code> to represent the bootstrap class
  577. * loader. This method will return <code>null</code> in such
  578. * implementations if this class loader's parent is the bootstrap
  579. * class loader.
  580. * <p>
  581. * If a security manager is present, and the caller's class loader is
  582. * not null and is not an ancestor of this class loader, then
  583. * this method calls the security manager's <code>checkPermission</code>
  584. * method with a <code>RuntimePermission("getClassLoader")</code>
  585. * permission to ensure it's ok to access the parent class loader.
  586. * If not, a <code>SecurityException</code> will be thrown.
  587. *
  588. * @throws SecurityException
  589. * if a security manager exists and its
  590. * <code>checkPermission</code> method doesn't allow
  591. * access to this class loader's parent class loader.
  592. *
  593. * @see SecurityManager#checkPermission
  594. * @see java.lang.RuntimePermission
  595. *
  596. * @since JDK1.2
  597. */
  598. public final ClassLoader getParent() {
  599. if (parent == null)
  600. return null;
  601. SecurityManager sm = System.getSecurityManager();
  602. if (sm != null) {
  603. ClassLoader ccl = getCallerClassLoader();
  604. if (ccl != null && !isAncestor(ccl)) {
  605. sm.checkPermission(getGetClassLoaderPerm());
  606. }
  607. }
  608. return parent;
  609. }
  610. /**
  611. * Sets the signers of a class. This should be called after defining a
  612. * class.
  613. * @param c the <code>Class</code> object
  614. * @param signers the signers for the class
  615. * @since JDK1.1
  616. */
  617. protected final void setSigners(Class c, Object[] signers) {
  618. check();
  619. c.setSigners(signers);
  620. }
  621. private Class findBootstrapClass0(String name)
  622. throws ClassNotFoundException {
  623. check();
  624. return findBootstrapClass(name);
  625. }
  626. private native Class defineClass0(String name, byte[] b, int off, int len,
  627. ProtectionDomain pd);
  628. private native void resolveClass0(Class c);
  629. private native Class findBootstrapClass(String name)
  630. throws ClassNotFoundException;
  631. /*
  632. * Check to make sure the class loader has been initialized.
  633. */
  634. private void check() {
  635. if (!initialized) {
  636. throw new SecurityException("ClassLoader object not initialized");
  637. }
  638. }
  639. /**
  640. * Finds the class with the given name if it had been previously loaded
  641. * through this class loader.
  642. *
  643. * @param name the class name
  644. * @return the <code>Class</code> object, or <code>null</code> if
  645. * the class has not been loaded
  646. * @since JDK1.1
  647. */
  648. protected native final Class findLoadedClass(String name);
  649. /**
  650. * Finds the resource with the given name. A resource is some data
  651. * (images, audio, text, etc) that can be accessed by class code in a way
  652. * that is independent of the location of the code.<p>
  653. *
  654. * The name of a resource is a "/"-separated path name that identifies
  655. * the resource.<p>
  656. *
  657. * This method will first search the parent class loader for the resource;
  658. * if the parent is <code>null</code> the path of the class loader
  659. * built-in to the virtual machine is searched. That failing, this method
  660. * will call <code>findResource</code> to find the resource.<p>
  661. *
  662. * @param name resource name
  663. * @return a URL for reading the resource, or <code>null</code> if
  664. * the resource could not be found or the caller doesn't have
  665. * adequate privileges to get the resource.
  666. * @since JDK1.1
  667. * @see #findResource(String)
  668. */
  669. public URL getResource(String name) {
  670. URL url;
  671. if (parent != null) {
  672. url = parent.getResource(name);
  673. } else {
  674. url = getBootstrapResource(name);
  675. }
  676. if (url == null) {
  677. url = findResource(name);
  678. }
  679. return url;
  680. }
  681. /**
  682. * Finds all the resources with the given name. A resource is some data
  683. * (images, audio, text, etc) that can be accessed by class code in a way
  684. * that is independent of the location of the code.<p>
  685. *
  686. * The name of a resource is a "/"-separated path name that identifies the
  687. * resource.<p>
  688. *
  689. * The search order is described in the documentation for {@link
  690. * #getResource(String)}.<p>
  691. *
  692. * @param name resource name
  693. * @return an enumeration of URL to the resource. If no resources could
  694. * be found, the enumeration will be empty. Resources that the
  695. * doesn't have access to will not be in the enumeration.
  696. * @since JDK1.2
  697. * @see #getResource
  698. * @see #findResources
  699. */
  700. public final Enumeration getResources(String name) throws IOException {
  701. Enumeration[] tmp = new Enumeration[2];
  702. if (parent != null) {
  703. tmp[0] = parent.getResources(name);
  704. } else {
  705. tmp[0] = getBootstrapResources(name);
  706. }
  707. tmp[1] = findResources(name);
  708. return new CompoundEnumeration(tmp);
  709. }
  710. /**
  711. * Returns an Enumeration of URLs representing all the resources with
  712. * the given name. Class loader implementations should override this
  713. * method to specify where to load resources from.
  714. *
  715. * @param name the resource name
  716. * @return an Enumeration of URLs for the resources
  717. * @since JDK1.2
  718. */
  719. protected Enumeration findResources(String name) throws IOException {
  720. return new CompoundEnumeration(new Enumeration[0]);
  721. }
  722. /**
  723. * Finds the resource with the given name. Class loader
  724. * implementations should override this method to specify where to
  725. * find resources.
  726. *
  727. * @param name the resource name
  728. * @return a URL for reading the resource, or <code>null</code>
  729. * if the resource could not be found
  730. * @since JDK1.2
  731. */
  732. protected URL findResource(String name) {
  733. return null;
  734. }
  735. /**
  736. * Find a resource of the specified name from the search path used to load
  737. * classes.<p>
  738. *
  739. * In JDK1.1, the search path used is that of the virtual machine's
  740. * built-in class loader.<p>
  741. *
  742. * Since JDK1.2, this method locates the resource through the system class
  743. * loader (see {@link #getSystemClassLoader()}).
  744. *
  745. * @param name the resource name
  746. * @return a URL for reading the resource, or <code>null</code> if
  747. * the resource could not be found
  748. * @since JDK1.1
  749. */
  750. public static URL getSystemResource(String name) {
  751. ClassLoader system = getSystemClassLoader();
  752. if (system == null) {
  753. return getBootstrapResource(name);
  754. }
  755. return system.getResource(name);
  756. }
  757. /**
  758. * Find resources from the VM's built-in classloader.
  759. */
  760. private static URL getBootstrapResource(String name) {
  761. URLClassPath ucp = getBootstrapClassPath();
  762. Resource res = ucp.getResource(name);
  763. return res != null ? res.getURL() : null;
  764. }
  765. /**
  766. * Finds all resources of the specified name from the search path used to
  767. * load classes. The resources thus found are returned as an
  768. * <code>Enumeration</code> of <code>URL</code> objects. <p>
  769. *
  770. * The search order is described in the documentation for {@link
  771. * #getSystemResource(String)}. <p>
  772. *
  773. * @param name the resource name
  774. * @return an enumeration of resource URLs
  775. * @since JDK1.2
  776. */
  777. public static Enumeration getSystemResources(String name)
  778. throws IOException
  779. {
  780. ClassLoader system = getSystemClassLoader();
  781. if (system == null) {
  782. return getBootstrapResources(name);
  783. }
  784. return system.getResources(name);
  785. }
  786. /**
  787. * Find resources from the VM's built-in classloader.
  788. */
  789. private static Enumeration getBootstrapResources(String name)
  790. throws IOException
  791. {
  792. final Enumeration e = getBootstrapClassPath().getResources(name);
  793. return new Enumeration () {
  794. public Object nextElement() {
  795. return ((Resource)e.nextElement()).getURL();
  796. }
  797. public boolean hasMoreElements() {
  798. return e.hasMoreElements();
  799. }
  800. };
  801. }
  802. /*
  803. * Returns the URLClassPath that is used for finding system resources.
  804. */
  805. static URLClassPath getBootstrapClassPath() {
  806. if (bootstrapClassPath == null) {
  807. bootstrapClassPath = sun.misc.Launcher.getBootstrapClassPath();
  808. }
  809. return bootstrapClassPath;
  810. }
  811. private static URLClassPath bootstrapClassPath;
  812. /**
  813. * Returns an input stream for reading the specified resource.
  814. *
  815. * The search order is described in the documentation for {@link
  816. * #getResource(String)}.<p>
  817. *
  818. * @param name the resource name
  819. * @return an input stream for reading the resource, or <code>null</code>
  820. * if the resource could not be found
  821. * @since JDK1.1
  822. */
  823. public InputStream getResourceAsStream(String name) {
  824. URL url = getResource(name);
  825. try {
  826. return url != null ? url.openStream() : null;
  827. } catch (IOException e) {
  828. return null;
  829. }
  830. }
  831. /**
  832. * Open for reading, a resource of the specified name from the search path
  833. * used to load classes.<p>
  834. *
  835. * The search order is described in the documentation for {@link
  836. * #getSystemResource(String)}. <p>
  837. *
  838. * @param name the resource name
  839. * @return an input stream for reading the resource, or <code>null</code>
  840. * if the resource could not be found
  841. * @since JDK1.1
  842. */
  843. public static InputStream getSystemResourceAsStream(String name) {
  844. URL url = getSystemResource(name);
  845. try {
  846. return url != null ? url.openStream() : null;
  847. } catch (IOException e) {
  848. return null;
  849. }
  850. }
  851. /**
  852. * Returns the system class loader for delegation. This is the default
  853. * delegation parent for new <code>ClassLoader</code> instances, and
  854. * is typically the class loader used to start the application.
  855. * <p>
  856. * If a security manager is present, and the caller's class loader is
  857. * not null and the caller's class loader is not the same as or an ancestor of
  858. * the system class loader, then
  859. * this method calls the security manager's <code>checkPermission</code>
  860. * method with a <code>RuntimePermission("getClassLoader")</code>
  861. * permission to ensure it's ok to access the system class loader.
  862. * If not, a <code>SecurityException</code> will be thrown.
  863. *
  864. * @return the system <code>ClassLoader</code> for delegation, or
  865. * <code>null</code> if none
  866. * @throws SecurityException
  867. * if a security manager exists and its
  868. * <code>checkPermission</code> method doesn't allow
  869. * access to the system class loader.
  870. * @see SecurityManager#checkPermission
  871. * @see java.lang.RuntimePermission
  872. * @since JDK1.2
  873. */
  874. public static ClassLoader getSystemClassLoader() {
  875. if (!sclSet) {
  876. // Workaround for 4154308 (JDK 1.2FCS build breaker)
  877. // Launcher l = Launcher.getLauncher();
  878. sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
  879. if (l != null) {
  880. scl = l.getClassLoader();
  881. }
  882. sclSet = true;
  883. }
  884. if (scl == null) {
  885. return null;
  886. }
  887. SecurityManager sm = System.getSecurityManager();
  888. if (sm != null) {
  889. ClassLoader ccl = getCallerClassLoader();
  890. if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) {
  891. sm.checkPermission(getGetClassLoaderPerm());
  892. }
  893. }
  894. return scl;
  895. }
  896. // Returns true if the specified class loader can be found
  897. // in this class loader's delegation chain.
  898. boolean isAncestor(ClassLoader cl) {
  899. ClassLoader acl = this;
  900. do {
  901. acl = acl.parent;
  902. if (cl == acl) {
  903. return true;
  904. }
  905. } while (acl != null);
  906. return false;
  907. }
  908. // Returns the caller's class loader, or null if none
  909. static native ClassLoader getCallerClassLoader();
  910. // The class loader for the system
  911. private static ClassLoader scl;
  912. // Set to true once the system class loader has been set
  913. private static boolean sclSet;
  914. // Permission to access system or parent class loader
  915. private static RuntimePermission getClassLoaderPerm = null;
  916. static RuntimePermission getGetClassLoaderPerm()
  917. {
  918. if (getClassLoaderPerm == null)
  919. getClassLoaderPerm = new RuntimePermission("getClassLoader");
  920. return getClassLoaderPerm;
  921. }
  922. /**
  923. * Defines a package by name in this ClassLoader. This allows class
  924. * loaders to define the packages for their classes. Packages must be
  925. * created before the class is defined, and package names must be
  926. * unique within a class loader and cannot be redefined or changed
  927. * once created.
  928. *
  929. * @param name the package name
  930. * @param specTitle the specification title
  931. * @param specVersion the specification version
  932. * @param specVendor the specification vendor
  933. * @param implTitle the implementation title
  934. * @param implVersion the implementation version
  935. * @param implVendor the implementation vendor
  936. * @param sealBase If not null, then this package is sealed with
  937. * respect to the given code source URL. Otherwise,
  938. * the package is not sealed.
  939. * @exception IllegalArgumentException if package name duplicates an
  940. * existing package either in this class loader or one of
  941. * its ancestors
  942. * @since JDK1.2
  943. */
  944. protected Package definePackage(String name, String specTitle,
  945. String specVersion, String specVendor,
  946. String implTitle, String implVersion,
  947. String implVendor, URL sealBase)
  948. throws IllegalArgumentException
  949. {
  950. synchronized (packages) {
  951. Package pkg = getPackage(name);
  952. if (pkg != null) {
  953. throw new IllegalArgumentException(name);
  954. }
  955. pkg = new Package(name, specTitle, specVersion, specVendor,
  956. implTitle, implVersion, implVendor,
  957. sealBase);
  958. packages.put(name, pkg);
  959. return pkg;
  960. }
  961. }
  962. /**
  963. * Returns a Package that has been defined by this class loader or any
  964. * of its ancestors.
  965. *
  966. * @param name the package name
  967. * @return the Package corresponding to the given name, or null if not
  968. * found
  969. * @since JDK1.2
  970. */
  971. protected Package getPackage(String name) {
  972. synchronized (packages) {
  973. Package pkg = (Package)packages.get(name);
  974. if (pkg == null) {
  975. if (parent != null) {
  976. pkg = parent.getPackage(name);
  977. } else {
  978. pkg = Package.getSystemPackage(name);
  979. }
  980. if (pkg != null) {
  981. packages.put(name, pkg);
  982. }
  983. }
  984. return pkg;
  985. }
  986. }
  987. /**
  988. * Returns all of the Packages defined by this class loader and its
  989. * ancestors.
  990. *
  991. * @since JDK1.2
  992. */
  993. protected Package[] getPackages() {
  994. Map map;
  995. synchronized (packages) {
  996. map = (Map)packages.clone();
  997. }
  998. Package[] pkgs;
  999. if (parent != null) {
  1000. pkgs = parent.getPackages();
  1001. } else {
  1002. pkgs = Package.getSystemPackages();
  1003. }
  1004. if (pkgs != null) {
  1005. for (int i = 0; i < pkgs.length; i++) {
  1006. map.put(pkgs[i].getName(), pkgs[i]);
  1007. }
  1008. }
  1009. return (Package[])map.values().toArray(new Package[map.size()]);
  1010. }
  1011. /**
  1012. * Returns the absolute path name of a native library. The VM
  1013. * invokes this method to locate the native libraries that belong
  1014. * to classes loaded with this class loader. If this method returns
  1015. * <code>null</code>, the VM searches the library along the path
  1016. * specified as the <code>java.library.path</code> property.
  1017. *
  1018. * @param libname the library name
  1019. * @return the absolute path of the native library
  1020. * @see java.lang.System#loadLibrary(java.lang.String)
  1021. * @see java.lang.System#mapLibraryName(java.lang.String)
  1022. * @since JDK1.2
  1023. */
  1024. protected String findLibrary(String libname) {
  1025. return null;
  1026. }
  1027. /**
  1028. * The inner class NativeLibrary denotes a loaded native library
  1029. * instance. Every classloader contains a vector of loaded native
  1030. * libraries in the private field <code>nativeLibraries</code>.
  1031. * The native libraries loaded into the system are entered into
  1032. * the <code>systemNativeLibraries</code> vector.
  1033. *
  1034. * Every native library reuqires a particular version of JNI. This
  1035. * is denoted by the private jniVersion field. This field is set
  1036. * by the VM when it loads the library, and used by the VM to pass
  1037. * the correct version of JNI to the native methods.
  1038. *
  1039. * @version 1.131, 11/29/01
  1040. * @see java.lang.ClassLoader
  1041. * @since JDK1.2
  1042. */
  1043. static class NativeLibrary {
  1044. /* opaque handle to native library, used in native code. */
  1045. long handle;
  1046. /* the version of JNI environment the native library requires. */
  1047. private int jniVersion;
  1048. /* the class from which the library is loaded, also indicates
  1049. the loader this native library belongs. */
  1050. private Class fromClass;
  1051. /* the canonicalized name of the native library. */
  1052. String name;
  1053. native void load(String name);
  1054. native long find(String name);
  1055. native void unload();
  1056. public NativeLibrary(Class fromClass, String name) {
  1057. this.name = name;
  1058. this.fromClass = fromClass;
  1059. }
  1060. protected void finalize() {
  1061. synchronized (loadedLibraryNames) {
  1062. if (fromClass.getClassLoader() != null && handle != 0) {
  1063. /* remove the native library name */
  1064. int size = loadedLibraryNames.size();
  1065. for (int i = 0; i < size; i++) {
  1066. if (name.equals(loadedLibraryNames.elementAt(i))) {
  1067. loadedLibraryNames.removeElementAt(i);
  1068. break;
  1069. }
  1070. }
  1071. /* unload the library. */
  1072. ClassLoader.nativeLibraryContext.push(this);
  1073. try {
  1074. unload();
  1075. } finally {
  1076. ClassLoader.nativeLibraryContext.pop();
  1077. }
  1078. }
  1079. }
  1080. }
  1081. /* Called in the VM to determine the context class in
  1082. JNI_Load/JNI_Unload */
  1083. static Class getFromClass() {
  1084. return ((NativeLibrary)
  1085. (ClassLoader.nativeLibraryContext.peek())).fromClass;
  1086. }
  1087. }
  1088. /* the "default" domain. Set as the default ProtectionDomain
  1089. * on newly created classses.
  1090. */
  1091. private ProtectionDomain defaultDomain = null;
  1092. /* the "default" permissions, shared by the default domains.
  1093. */
  1094. private static PermissionCollection defaultPermissions = null;
  1095. /*
  1096. * returns (and initializes) the default domain.
  1097. */
  1098. private ProtectionDomain getDefaultDomain() {
  1099. if (defaultDomain == null) {
  1100. synchronized(ClassLoader.class) {
  1101. if (defaultPermissions == null) {
  1102. defaultPermissions = (PermissionCollection)
  1103. AccessController.doPrivileged(new PrivilegedAction() {
  1104. public Object run() {
  1105. CodeSource cs = new CodeSource(null, null);
  1106. return Policy.getPolicy().getPermissions(cs);
  1107. }
  1108. });
  1109. }
  1110. if (defaultDomain == null) {
  1111. CodeSource cs = new CodeSource(null, null);
  1112. defaultDomain = new ProtectionDomain(cs,
  1113. defaultPermissions);
  1114. }
  1115. }
  1116. }
  1117. return defaultDomain;
  1118. }
  1119. /* All native library names we've loaded. */
  1120. private static Vector loadedLibraryNames = new Vector();
  1121. /* Native libraries belonging to system classes. */
  1122. private static Vector systemNativeLibraries = new Vector();
  1123. /* Native libraries associated with the class loader. */
  1124. private Vector nativeLibraries = new Vector();
  1125. /* native libraries being loaded/unloaded. */
  1126. private static Stack nativeLibraryContext = new Stack();
  1127. /* The paths searched for libraries */
  1128. static private String usr_paths[];
  1129. static private String sys_paths[];
  1130. private static String[] initializePath(String propname) {
  1131. String ldpath = System.getProperty(propname, "");
  1132. String ps = File.pathSeparator;
  1133. int ldlen = ldpath.length();
  1134. int i, j, n;
  1135. // Count the separators in the path
  1136. i = ldpath.indexOf(ps);
  1137. n = 0;
  1138. while (i >= 0) {
  1139. n++;
  1140. i = ldpath.indexOf(ps, i+1);
  1141. }
  1142. // allocate the array of paths - n :'s = n + 1 path elements
  1143. String[] paths = new String[n + 1];
  1144. // Fill the array with paths from the ldpath
  1145. n = i = 0;
  1146. j = ldpath.indexOf(ps);
  1147. while (j >= 0) {
  1148. if (j - i > 0) {
  1149. paths[n++] = ldpath.substring(i, j);
  1150. } else if (j - i == 0) {
  1151. paths[n++] = ".";
  1152. }
  1153. i = j + 1;
  1154. j = ldpath.indexOf(ps, i);
  1155. }
  1156. paths[n] = ldpath.substring(i, ldlen);
  1157. return paths;
  1158. }
  1159. /* Called in the java.lang.Runtime class to implement load
  1160. * and loadLibrary.
  1161. */
  1162. static void loadLibrary(Class fromClass, String name,
  1163. boolean isAbsolute) {
  1164. ClassLoader loader =
  1165. (fromClass == null) ? null : fromClass.getClassLoader();
  1166. if (sys_paths == null) {
  1167. usr_paths = initializePath("java.library.path");
  1168. sys_paths = initializePath("sun.boot.library.path");
  1169. }
  1170. if (isAbsolute) {
  1171. if (loadLibrary0(fromClass, new File(name))) {
  1172. return;
  1173. }
  1174. throw new UnsatisfiedLinkError("Can't load library: " + name);
  1175. }
  1176. if (loader != null) {
  1177. String libfilename = loader.findLibrary(name);
  1178. if (libfilename != null) {
  1179. File libfile = new File(libfilename);
  1180. if (!libfile.isAbsolute()) {
  1181. throw new UnsatisfiedLinkError(
  1182. "ClassLoader.findClass failed to return an absolute path: " + libfilename);
  1183. }
  1184. if (loadLibrary0(fromClass, libfile)) {
  1185. return;
  1186. }
  1187. throw new UnsatisfiedLinkError ("Can't load " + libfilename);
  1188. }
  1189. }
  1190. for (int i = 0 ; i < sys_paths.length ; i++) {
  1191. File libfile = new File(sys_paths[i], System.mapLibraryName(name));
  1192. if (loadLibrary0(fromClass, libfile)) {
  1193. return;
  1194. }
  1195. }
  1196. if (loader != null) {
  1197. for (int i = 0 ; i < usr_paths.length ; i++) {
  1198. File libfile = new File(usr_paths[i],
  1199. System.mapLibraryName(name));
  1200. if (loadLibrary0(fromClass, libfile)) {
  1201. return;
  1202. }
  1203. }
  1204. }
  1205. // Oops, it failed
  1206. throw new UnsatisfiedLinkError("no " + name + " in java.library.path");
  1207. }
  1208. private static boolean loadLibrary0(Class fromClass, final File file) {
  1209. Boolean exists = (Boolean)
  1210. AccessController.doPrivileged(new PrivilegedAction() {
  1211. public Object run() {
  1212. return new Boolean(file.exists());
  1213. }
  1214. });
  1215. if (!exists.booleanValue()) {
  1216. return false;
  1217. }
  1218. String name;
  1219. try {
  1220. name = file.getCanonicalPath();
  1221. } catch (IOException e) {
  1222. return false;
  1223. }
  1224. ClassLoader loader =
  1225. (fromClass == null) ? null : fromClass.getClassLoader();
  1226. Vector libs =
  1227. loader != null ? loader.nativeLibraries : systemNativeLibraries;
  1228. synchronized (libs) {
  1229. int size = libs.size();
  1230. for (int i = 0; i < size; i++) {
  1231. NativeLibrary lib = (NativeLibrary)libs.elementAt(i);
  1232. if (name.equals(lib.name)) {
  1233. return true;
  1234. }
  1235. }
  1236. synchronized (loadedLibraryNames) {
  1237. if (loadedLibraryNames.contains(name)) {
  1238. throw new UnsatisfiedLinkError
  1239. ("Native Library " +
  1240. name +
  1241. " already loaded in another classloader");
  1242. }
  1243. /* If the library is being loaded (must be by
  1244. * the same thread, because Runtime.load and
  1245. * Runtime.loadLibrary are synchronous). The
  1246. * reason is can occur is that the JNI_OnLoad
  1247. * function can cause another loadLibrary call.
  1248. *
  1249. * Thus we can use a static stack to hold the list
  1250. * of libraries we are loading.
  1251. *
  1252. * If there is a pending load operation for the
  1253. * library, we immediately return success; otherwise,
  1254. * we raise UnsatisfiedLinkError.
  1255. */
  1256. int n = nativeLibraryContext.size();
  1257. for (int i = 0; i < n; i++) {
  1258. NativeLibrary lib = (NativeLibrary)
  1259. nativeLibraryContext.elementAt(i);
  1260. if (name.equals(lib.name)) {
  1261. if (loader == lib.fromClass.getClassLoader()) {
  1262. return true;
  1263. } else {
  1264. throw new UnsatisfiedLinkError
  1265. ("Native Library " +
  1266. name +
  1267. " is being loaded in another classloader");
  1268. }
  1269. }
  1270. }
  1271. NativeLibrary lib = new NativeLibrary(fromClass, name);
  1272. nativeLibraryContext.push(lib);
  1273. try {
  1274. lib.load(name);
  1275. } finally {
  1276. nativeLibraryContext.pop();
  1277. }
  1278. if (lib.handle != 0) {
  1279. loadedLibraryNames.addElement(name);
  1280. libs.addElement(lib);
  1281. return true;
  1282. }
  1283. return false;
  1284. }
  1285. }
  1286. }
  1287. /* Called in the VM class linking code. */
  1288. static long findNative(ClassLoader loader, String name) {
  1289. Vector libs =
  1290. loader != null ? loader.nativeLibraries : systemNativeLibraries;
  1291. synchronized (libs) {
  1292. int size = libs.size();
  1293. for (int i = 0; i < size; i++) {
  1294. NativeLibrary lib = (NativeLibrary)libs.elementAt(i);
  1295. long entry = lib.find(name);
  1296. if (entry != 0)
  1297. return entry;
  1298. }
  1299. }
  1300. return 0;
  1301. }
  1302. }