1. /*
  2. * @(#)ClassLoader.java 1.169 03/01/23
  3. *
  4. * Copyright 2003 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.File;
  11. import java.lang.reflect.Constructor;
  12. import java.lang.reflect.InvocationTargetException;
  13. import java.net.MalformedURLException;
  14. import java.net.URL;
  15. import java.security.AccessController;
  16. import java.security.AccessControlContext;
  17. import java.security.CodeSource;
  18. import java.security.Policy;
  19. import java.security.PrivilegedAction;
  20. import java.security.PrivilegedActionException;
  21. import java.security.PrivilegedExceptionAction;
  22. import java.security.ProtectionDomain;
  23. import java.util.Enumeration;
  24. import java.util.Hashtable;
  25. import java.util.HashMap;
  26. import java.util.HashSet;
  27. import java.util.Set;
  28. import java.util.Stack;
  29. import java.util.Map;
  30. import java.util.Vector;
  31. import sun.misc.ClassFileTransformer;
  32. import sun.misc.CompoundEnumeration;
  33. import sun.misc.Resource;
  34. import sun.misc.URLClassPath;
  35. import sun.reflect.Reflection;
  36. import sun.security.util.SecurityConstants;
  37. /**
  38. * A class loader is an object that is responsible for loading classes. The
  39. * class <tt>ClassLoader</tt> is an abstract class. Given the name of a
  40. * class, a class loader should attempt to locate or generate data that
  41. * constitutes a definition for the class. A typical strategy is to transform
  42. * the name into a file name and then read a "class file" of that name
  43. * from a file system.
  44. *
  45. * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
  46. * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
  47. * it.
  48. *
  49. * <p> <tt>Class</tt> objects for array classes are not created by class
  50. * loaders, but are created automatically as required by the Java runtime.
  51. * The class loader for an array class, as returned by {@link
  52. * Class#getClassLoader()} is the same as the class loader for its element
  53. * type; if the element type is a primitive type, then the array class has no
  54. * class loader.
  55. *
  56. * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
  57. * extend the manner in which the Java virtual machine dynamically loads
  58. * classes.
  59. *
  60. * <p> Class loaders may typically be used by security managers to indicate
  61. * security domains.
  62. *
  63. * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
  64. * classes and resources. Each instance of <tt>ClassLoader</tt> has an
  65. * associated parent class loader. When requested to find a class or
  66. * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
  67. * class or resource to its parent class loader before attempting to find the
  68. * class or resource itself. The virtual machine's built-in class loader,
  69. * called the "bootstrap class loader", does not itself have a parent but may
  70. * serve as the parent of a <tt>ClassLoader</tt> instance.
  71. *
  72. * <p> Normally, the Java virtual machine loads classes from the local file
  73. * system in a platform-dependent manner. For example, on UNIX systems, the
  74. * virtual machine loads classes from the directory defined by the
  75. * <tt>CLASSPATH</tt> environment variable.
  76. *
  77. * <p> However, some classes may not originate from a file; they may originate
  78. * from other sources, such as the network, or they could be constructed by an
  79. * application. The method {@link #defineClass(String, byte[], int, int)
  80. * <tt>defineClass</tt>} converts an array of bytes into an instance of class
  81. * <tt>Class</tt>. Instances of this newly defined class can be created using
  82. * {@link Class#newInstance <tt>Class.newInstance</tt>}.
  83. *
  84. * <p> The methods and constructors of objects created by a class loader may
  85. * reference other classes. To determine the class(es) referred to, the Java
  86. * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
  87. * the class loader that originally created the class.
  88. *
  89. * <p> For example, an application could create a network class loader to
  90. * download class files from a server. Sample code might look like:
  91. *
  92. * <blockquote><pre>
  93. * ClassLoader loader = new NetworkClassLoader(host, port);
  94. * Object main = loader.loadClass("Main", true).newInstance();
  95. *  . . .
  96. * </pre></blockquote>
  97. *
  98. * <p> The network class loader subclass must define the methods {@link
  99. * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
  100. * from the network. Once it has downloaded the bytes that make up the class,
  101. * it should use the method {@link #defineClass <tt>defineClass</tt>} to
  102. * create a class instance. A sample implementation is:
  103. *
  104. * <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>
  120. *
  121. * @version 1.169, 01/23/03
  122. * @see #resolveClass(Class)
  123. * @since 1.0
  124. */
  125. public abstract class ClassLoader {
  126. private static native void registerNatives();
  127. static {
  128. registerNatives();
  129. }
  130. // If initialization succeed this is set to true and security checks will
  131. // succeed. Otherwise the object is not initialized and the object is
  132. // useless.
  133. private boolean initialized = false;
  134. // The parent class loader for delegation
  135. private ClassLoader parent;
  136. // Hashtable that maps packages to certs
  137. private Hashtable package2certs = new Hashtable(11);
  138. // Shared among all packages with unsigned classes
  139. java.security.cert.Certificate[] nocerts;
  140. // The classes loaded by this class loader. The only purpose of this table
  141. // is to keep the classes from being GC'ed until the loader is GC'ed.
  142. private Vector classes = new Vector();
  143. // The initiating protection domains for all classes loaded by this loader
  144. private Set domains = new HashSet();
  145. // Invoked by the VM to record every loaded class with this loader.
  146. void addClass(Class c) {
  147. classes.addElement(c);
  148. }
  149. // The packages defined in this class loader. Each package name is mapped
  150. // to its corresponding Package object.
  151. private HashMap packages = new HashMap();
  152. /**
  153. * Creates a new class loader using the specified parent class loader for
  154. * delegation.
  155. *
  156. * <p> If there is a security manager, its {@link
  157. * SecurityManager#checkCreateClassLoader()
  158. * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
  159. * a security exception. </p>
  160. *
  161. * @param parent
  162. * The parent class loader
  163. *
  164. * @throws SecurityException
  165. * If a security manager exists and its
  166. * <tt>checkCreateClassLoader</tt> method doesn't allow creation
  167. * of a new class loader.
  168. *
  169. * @since 1.2
  170. */
  171. protected ClassLoader(ClassLoader parent) {
  172. SecurityManager security = System.getSecurityManager();
  173. if (security != null) {
  174. security.checkCreateClassLoader();
  175. }
  176. this.parent = parent;
  177. initialized = true;
  178. }
  179. /**
  180. * Creates a new class loader using the <tt>ClassLoader</tt> returned by
  181. * the method {@link #getSystemClassLoader()
  182. * <tt>getSystemClassLoader()</tt>} as the parent class loader.
  183. *
  184. * <p> If there is a security manager, its {@link
  185. * SecurityManager#checkCreateClassLoader()
  186. * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
  187. * a security exception. </p>
  188. *
  189. * @throws SecurityException
  190. * If a security manager exists and its
  191. * <tt>checkCreateClassLoader</tt> method doesn't allow creation
  192. * of a new class loader.
  193. */
  194. protected ClassLoader() {
  195. SecurityManager security = System.getSecurityManager();
  196. if (security != null) {
  197. security.checkCreateClassLoader();
  198. }
  199. this.parent = getSystemClassLoader();
  200. initialized = true;
  201. }
  202. // -- Class --
  203. /**
  204. * Loads the class with the specified name. This method searches for
  205. * classes in the same manner as the {@link #loadClass(String, boolean)}
  206. * method. It is invoked by the Java virtual machine to resolve class
  207. * references. Invoking this method is equivalent to invoking {@link
  208. * #loadClass(String, boolean) <tt>loadClass(name, false)</tt>}. </p>
  209. *
  210. * @param name
  211. * The name of the class
  212. *
  213. * @return The resulting <tt>Class</tt> object
  214. *
  215. * @throws ClassNotFoundException
  216. * If the class was not found
  217. */
  218. public Class loadClass(String name) throws ClassNotFoundException {
  219. return loadClass(name, false);
  220. }
  221. /**
  222. * Loads the class with the specified name. The default implementation
  223. * of this method searches for classes in the following order:
  224. *
  225. * <p><ol>
  226. *
  227. * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
  228. * has already been loaded. </p></li>
  229. *
  230. * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
  231. * on the parent class loader. If the parent is <tt>null</tt> the class
  232. * loader built-in to the virtual machine is used, instead. </p></li>
  233. *
  234. * <li><p> Invoke the {@link #findClass(String)} method to find the
  235. * class. </p></li>
  236. *
  237. * </ol>
  238. *
  239. * <p> If the class was found using the above steps, and the
  240. * <tt>resolve</tt> flag is true, this method will then invoke the {@link
  241. * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
  242. *
  243. * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
  244. * #findClass(String)}, rather than this method. </p>
  245. *
  246. * @param name
  247. * The name of the class
  248. *
  249. * @param resolve
  250. * If <tt>true</tt> then resolve the class
  251. *
  252. * @return The resulting <tt>Class</tt> object
  253. *
  254. * @throws ClassNotFoundException
  255. * If the class could not be found
  256. */
  257. protected synchronized Class loadClass(String name, boolean resolve)
  258. throws ClassNotFoundException
  259. {
  260. // First, check if the class has already been loaded
  261. Class c = findLoadedClass(name);
  262. if (c == null) {
  263. try {
  264. if (parent != null) {
  265. c = parent.loadClass(name, false);
  266. } else {
  267. c = findBootstrapClass0(name);
  268. }
  269. } catch (ClassNotFoundException e) {
  270. // If still not found, then invoke findClass in order
  271. // to find the class.
  272. c = findClass(name);
  273. }
  274. }
  275. if (resolve) {
  276. resolveClass(c);
  277. }
  278. return c;
  279. }
  280. // This method is invoked by the virtual machine to load a class.
  281. private synchronized Class loadClassInternal(String name)
  282. throws ClassNotFoundException
  283. {
  284. return loadClass(name);
  285. }
  286. private void checkPackageAccess(Class cls, ProtectionDomain pd) {
  287. final SecurityManager sm = System.getSecurityManager();
  288. if (sm != null) {
  289. final String name = cls.getName();
  290. final int i = name.lastIndexOf('.');
  291. if (i != -1) {
  292. AccessController.doPrivileged(new PrivilegedAction() {
  293. public Object run() {
  294. sm.checkPackageAccess(name.substring(0, i));
  295. return null;
  296. }
  297. }, new AccessControlContext(new ProtectionDomain[] {pd}));
  298. }
  299. }
  300. domains.add(pd);
  301. }
  302. /**
  303. * Finds the specified class. This method should be overridden by class
  304. * loader implementations that follow the delegation model for loading
  305. * classes, and will be invoked by the {@link #loadClass
  306. * <tt>loadClass</tt>} method after checking the parent class loader for
  307. * the requested class. The default implementation throws a
  308. * <tt>ClassNotFoundException</tt>. </p>
  309. *
  310. * @param name
  311. * The name of the class
  312. *
  313. * @return The resulting <tt>Class</tt> object
  314. *
  315. * @throws ClassNotFoundException
  316. * If the class could not be found
  317. *
  318. * @since 1.2
  319. */
  320. protected Class findClass(String name) throws ClassNotFoundException {
  321. throw new ClassNotFoundException(name);
  322. }
  323. /**
  324. * Converts an array of bytes into an instance of class <tt>Class</tt>.
  325. * Before the <tt>Class</tt> can be used it must be resolved. This method
  326. * is deprecated in favor of the version that takes the class name as its
  327. * first argument, and is more secure.
  328. *
  329. * @param b
  330. * The bytes that make up the class data. The bytes in positions
  331. * <tt>off</tt> through <tt>off+len-1</tt> should have the format
  332. * of a valid class file as defined by the <a
  333. * href="http://java.sun.com/docs/books/vmspec/">Java Virtual
  334. * Machine Specification</a>.
  335. *
  336. * @param off
  337. * The start offset in <tt>b</tt> of the class data
  338. *
  339. * @param len
  340. * The length of the class data
  341. *
  342. * @return The <tt>Class</tt> object that was created from the specified
  343. * class data
  344. *
  345. * @throws ClassFormatError
  346. * If the data did not contain a valid class
  347. *
  348. * @throws IndexOutOfBoundsException
  349. * If either <tt>off</tt> or <tt>len</tt> is negative, or if
  350. * <tt>off+len</tt> is greater than <tt>b.length</tt>.
  351. *
  352. * @see #loadClass(String, boolean)
  353. * @see #resolveClass(Class)
  354. *
  355. * @deprecated Replaced by {@link #defineClass(String, byte[], int, int)
  356. * defineClass(String, byte[], int, int)}
  357. */
  358. protected final Class defineClass(byte[] b, int off, int len)
  359. throws ClassFormatError
  360. {
  361. return defineClass(null, b, off, len, null);
  362. }
  363. /**
  364. * Converts an array of bytes into an instance of class <tt>Class</tt>.
  365. * Before the <tt>Class</tt> can be used it must be resolved.
  366. *
  367. * <p> This method assigns a default {@link java.security.ProtectionDomain
  368. * <tt>ProtectionDomain</tt>} to the newly defined class. The
  369. * <tt>ProtectionDomain</tt> is effectively granted the same set of
  370. * permissions returned when {@link
  371. * java.security.Policy#getPermissions(java.security.CodeSource)
  372. * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>}
  373. * is invoked. The default domain is created on the first invocation of
  374. * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>},
  375. * and re-used on subsequent invocations.
  376. *
  377. * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use
  378. * the {@link #defineClass(String, byte[], int, int,
  379. * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a
  380. * <tt>ProtectionDomain</tt> as one of its arguments. </p>
  381. *
  382. * @param name
  383. * The expected name of the class, or <tt>null</tt>
  384. * if not known, using '<tt>.</tt>' and not '<tt>/</tt>' as the
  385. * separator and without a trailing <tt>.class</tt> suffix.
  386. *
  387. * @param b
  388. * The bytes that make up the class data. The bytes in positions
  389. * <tt>off</tt> through <tt>off+len-1</tt> should have the format
  390. * of a valid class file as defined by the <a
  391. * href="http://java.sun.com/docs/books/vmspec/">Java Virtual
  392. * Machine Specification</a>.
  393. *
  394. * @param off
  395. * The start offset in <tt>b</tt> of the class data
  396. *
  397. * @param len
  398. * The length of the class data
  399. *
  400. * @return The <tt>Class</tt> object that was created from the specified
  401. * class data.
  402. *
  403. * @throws ClassFormatError
  404. * If the data did not contain a valid class
  405. *
  406. * @throws IndexOutOfBoundsException
  407. * If either <tt>off</tt> or <tt>len</tt> is negative, or if
  408. * <tt>off+len</tt> is greater than <tt>b.length</tt>.
  409. *
  410. * @throws SecurityException
  411. * If an attempt is made to add this class to a package that
  412. * contains classes that were signed by a different set of
  413. * certificates than this class (which is unsigned), or if the
  414. * class name begins with "<tt>java.</tt>".
  415. *
  416. * @see #loadClass(String, boolean)
  417. * @see #resolveClass(Class)
  418. * @see java.security.CodeSource
  419. * @see java.security.SecureClassLoader
  420. *
  421. * @since 1.1
  422. */
  423. protected final Class defineClass(String name, byte[] b, int off, int len)
  424. throws ClassFormatError
  425. {
  426. return defineClass(name, b, off, len, null);
  427. }
  428. /**
  429. * Converts an array of bytes into an instance of class <tt>Class</tt>,
  430. * with an optional <tt>ProtectionDomain</tt>. If the domain is
  431. * <tt>null</tt>, then a default domain will be assigned to the class as
  432. * specified in the documentation for {@link #defineClass(String, byte[],
  433. * int, int)}. Before the class can be used it must be resolved.
  434. *
  435. * <p> The first class defined in a package determines the exact set of
  436. * certificates that all subsequent classes defined in that package must
  437. * contain. The set of certificates for a class is obtained from the
  438. * {@link java.security.CodeSource <tt>CodeSource</tt>} within the
  439. * <tt>ProtectionDomain</tt> of the class. Any classes added to that
  440. * package must contain the same set of certificates or a
  441. * <tt>SecurityException</tt> will be thrown. Note that if the
  442. * <tt>name</tt> argument is <tt>null</tt>, this check is not performed.
  443. * You should always pass in the name of the class you are defining as
  444. * well as the bytes. This ensures that the class you are defining is
  445. * indeed the class you think it is.
  446. *
  447. * <p> The specified class name cannot begin with "<tt>java.</tt>", since
  448. * all classes in the "<tt>java.*</tt> packages can only be defined by the
  449. * bootstrap class loader. If the name parameter is not <tt>null</tt>, it
  450. * must be equal to the name of the class specified by the byte array
  451. * "<tt>b</tt>", otherwise a {@link <tt>NoClassDefFoundError</tt>} will be
  452. * thrown. </p>
  453. *
  454. * @param name
  455. * The expected name of the class, or <tt>null</tt> if not known,
  456. * using '<tt>.</tt>' and not '<tt>/</tt>' as the separator and
  457. * without a trailing "<tt>.class</tt>" suffix.
  458. *
  459. * @param b
  460. * The bytes that make up the class data. The bytes in positions
  461. * <tt>off</tt> through <tt>off+len-1</tt> should have the format
  462. * of a valid class file as defined by the <a
  463. * href="http://java.sun.com/docs/books/vmspec/">Java Virtual
  464. * Machine Specification</a>.
  465. *
  466. * @param off
  467. * The start offset in <tt>b</tt> of the class data
  468. *
  469. * @param len
  470. * The length of the class data
  471. *
  472. * @param protectionDomain
  473. * The ProtectionDomain of the class
  474. *
  475. * @return The <tt>Class</tt> object created from the data,
  476. * and optional <tt>ProtectionDomain</tt>.
  477. *
  478. * @throws ClassFormatError
  479. * If the data did not contain a valid class
  480. *
  481. * @throws NoClassDefFoundError
  482. * If <tt>name</tt> is not equal to the name of the class
  483. * specified by <tt>b</tt>
  484. *
  485. * @throws IndexOutOfBoundsException
  486. * If either <tt>off</tt> or <tt>len</tt> is negative, or if
  487. * <tt>off+len</tt> is greater than <tt>b.length</tt>.
  488. *
  489. * @throws SecurityException
  490. * If an attempt is made to add this class to a package that
  491. * contains classes that were signed by a different set of
  492. * certificates than this class, or if the class name begins with
  493. * "<tt>java.</tt>".
  494. */
  495. protected final Class defineClass(String name, byte[] b, int off, int len,
  496. ProtectionDomain protectionDomain)
  497. throws ClassFormatError
  498. {
  499. check();
  500. if ((name != null) && name.startsWith("java.")) {
  501. throw new SecurityException("Prohibited package name: " +
  502. name.substring(0, name.lastIndexOf('.')));
  503. }
  504. if (protectionDomain == null) {
  505. protectionDomain = getDefaultDomain();
  506. }
  507. if (name != null)
  508. checkCerts(name, protectionDomain.getCodeSource());
  509. Class c = null;
  510. try {
  511. c = defineClass0(name, b, off, len, protectionDomain);
  512. } catch (ClassFormatError cfe) {
  513. // Class format error - try to transform the bytecode and
  514. // define the class again
  515. //
  516. Object[] transformers = ClassFileTransformer.getTransformers();
  517. for (int i = 0; transformers != null && i < transformers.length; i++) {
  518. try {
  519. // Transform byte code using transformer
  520. byte[] tb = ((ClassFileTransformer) transformers[i]).transform(b, off, len);
  521. c = defineClass0(name, tb, 0, tb.length, protectionDomain);
  522. break;
  523. } catch (ClassFormatError cfe2) {
  524. // If ClassFormatError occurs, try next transformer
  525. }
  526. }
  527. // Rethrow original ClassFormatError if unable to transform
  528. // bytecode to well-formed
  529. //
  530. if (c == null)
  531. throw cfe;
  532. }
  533. if (protectionDomain.getCodeSource() != null) {
  534. java.security.cert.Certificate certs[] =
  535. protectionDomain.getCodeSource().getCertificates();
  536. if (certs != null)
  537. setSigners(c, certs);
  538. }
  539. return c;
  540. }
  541. private native Class defineClass0(String name, byte[] b, int off, int len,
  542. ProtectionDomain pd);
  543. private synchronized void checkCerts(String name, CodeSource cs) {
  544. int i = name.lastIndexOf('.');
  545. String pname = (i == -1) ? "" : name.substring(0, i);
  546. java.security.cert.Certificate[] pcerts =
  547. (java.security.cert.Certificate[]) package2certs.get(pname);
  548. if (pcerts == null) {
  549. // first class in this package gets to define which
  550. // certificates must be the same for all other classes
  551. // in this package
  552. if (cs != null) {
  553. pcerts = cs.getCertificates();
  554. }
  555. if (pcerts == null) {
  556. if (nocerts == null)
  557. nocerts = new java.security.cert.Certificate[0];
  558. pcerts = nocerts;
  559. }
  560. package2certs.put(pname, pcerts);
  561. } else {
  562. java.security.cert.Certificate[] certs = null;
  563. if (cs != null) {
  564. certs = cs.getCertificates();
  565. }
  566. if (!compareCerts(pcerts, certs)) {
  567. throw new SecurityException("class \""+ name +
  568. "\"'s signer information does not match signer information of other classes in the same package");
  569. }
  570. }
  571. }
  572. /**
  573. * check to make sure the certs for the new class (certs) are the same as
  574. * the certs for the first class inserted in the package (pcerts)
  575. */
  576. private boolean compareCerts(java.security.cert.Certificate[] pcerts,
  577. java.security.cert.Certificate[] certs)
  578. {
  579. // certs can be null, indicating no certs.
  580. if ((certs == null) || (certs.length == 0)) {
  581. return pcerts.length == 0;
  582. }
  583. // the length must be the same at this point
  584. if (certs.length != pcerts.length)
  585. return false;
  586. // go through and make sure all the certs in one array
  587. // are in the other and vice-versa.
  588. boolean match;
  589. for (int i = 0; i < certs.length; i++) {
  590. match = false;
  591. for (int j = 0; j < pcerts.length; j++) {
  592. if (certs[i].equals(pcerts[j])) {
  593. match = true;
  594. break;
  595. }
  596. }
  597. if (!match) return false;
  598. }
  599. // now do the same for pcerts
  600. for (int i = 0; i < pcerts.length; i++) {
  601. match = false;
  602. for (int j = 0; j < certs.length; j++) {
  603. if (pcerts[i].equals(certs[j])) {
  604. match = true;
  605. break;
  606. }
  607. }
  608. if (!match) return false;
  609. }
  610. return true;
  611. }
  612. /**
  613. * Links the specified class. This (misleadingly named) method may be
  614. * used by a class loader to link a class. If the class <tt>c</tt> has
  615. * already been linked, then this method simply returns. Otherwise, the
  616. * class is linked as described in the "Execution" chapter of the <a
  617. * href="http://java.sun.com/docs/books/jls/">Java Language Specification</a>.
  618. * </p>
  619. *
  620. * @param c
  621. * The class to link
  622. *
  623. * @throws NullPointerException
  624. * If <tt>c</tt> is <tt>null</tt>.
  625. *
  626. * @see #defineClass(String, byte[], int, int)
  627. */
  628. protected final void resolveClass(Class c) {
  629. check();
  630. resolveClass0(c);
  631. }
  632. private native void resolveClass0(Class c);
  633. /**
  634. * Finds a class with the specified name, loading it if necessary.
  635. *
  636. * <p> This method loads the class through the system class loader (see
  637. * {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned
  638. * might have more than one <tt>ClassLoader</tt> associated with it.
  639. * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,
  640. * because most class loaders need to override just {@link
  641. * #findClass(String)}. </p>
  642. *
  643. * @param name
  644. * The name of the class that is to be found
  645. *
  646. * @return The <tt>Class</tt> object for the specified <tt>name</tt>
  647. *
  648. * @throws ClassNotFoundException
  649. * If the class could not be found
  650. *
  651. * @see #ClassLoader(ClassLoader)
  652. * @see #getParent()
  653. */
  654. protected final Class findSystemClass(String name)
  655. throws ClassNotFoundException
  656. {
  657. check();
  658. ClassLoader system = getSystemClassLoader();
  659. if (system == null) {
  660. return findBootstrapClass(name);
  661. }
  662. return system.loadClass(name);
  663. }
  664. private Class findBootstrapClass0(String name)
  665. throws ClassNotFoundException {
  666. check();
  667. return findBootstrapClass(name);
  668. }
  669. private native Class findBootstrapClass(String name)
  670. throws ClassNotFoundException;
  671. // Check to make sure the class loader has been initialized.
  672. private void check() {
  673. if (!initialized) {
  674. throw new SecurityException("ClassLoader object not initialized");
  675. }
  676. }
  677. /**
  678. * Returns the class with the given name if this loader has been recorded
  679. * by the Java virtual machine as an initiating loader of a class with
  680. * that name. Otherwise <tt>null</tt> is returned. </p>
  681. *
  682. * @param name
  683. * The class name
  684. *
  685. * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has
  686. * not been loaded
  687. *
  688. * @since 1.1
  689. */
  690. protected native final Class findLoadedClass(String name);
  691. /**
  692. * Sets the signers of a class. This should be invoked after defining a
  693. * class. </p>
  694. *
  695. * @param c
  696. * The <tt>Class</tt> object
  697. *
  698. * @param signers
  699. * The signers for the class
  700. *
  701. * @since 1.1
  702. */
  703. protected final void setSigners(Class c, Object[] signers) {
  704. check();
  705. c.setSigners(signers);
  706. }
  707. // -- Resource --
  708. /**
  709. * Finds the resource with the given name. A resource is some data
  710. * (images, audio, text, etc) that can be accessed by class code in a way
  711. * that is independent of the location of the code.
  712. *
  713. * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
  714. * identifies the resource.
  715. *
  716. * <p> This method will first search the parent class loader for the
  717. * resource; if the parent is <tt>null</tt> the path of the class loader
  718. * built-in to the virtual machine is searched. That failing, this method
  719. * will invoke {@link #findResource(String)} to find the resource. </p>
  720. *
  721. * @param name
  722. * The resource name
  723. *
  724. * @return A <tt>URL</tt> object for reading the resource, or
  725. * <tt>null</tt> if the resource could not be found or the invoker
  726. * doesn't have adequate privileges to get the resource.
  727. *
  728. * @since 1.1
  729. */
  730. public URL getResource(String name) {
  731. URL url;
  732. if (parent != null) {
  733. url = parent.getResource(name);
  734. } else {
  735. url = getBootstrapResource(name);
  736. }
  737. if (url == null) {
  738. url = findResource(name);
  739. }
  740. return url;
  741. }
  742. /**
  743. * Finds all the resources with the given name. A resource is some data
  744. * (images, audio, text, etc) that can be accessed by class code in a way
  745. * that is independent of the location of the code.
  746. *
  747. * <p>The name of a resource is a <tt>/</tt>-separated path name that
  748. * identifies the resource.
  749. *
  750. * <p> The search order is described in the documentation for {@link
  751. * #getResource(String)}. </p>
  752. *
  753. * @param name
  754. * The resource name
  755. *
  756. * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
  757. * the resource. If no resources could be found, the enumeration
  758. * will be empty. Resources that the class loader doesn't have
  759. * access to will not be in the enumeration.
  760. *
  761. * @throws IOException
  762. * If I/O errors occur
  763. *
  764. * @see #findResources(String)
  765. *
  766. * @since 1.2
  767. */
  768. public final Enumeration getResources(String name) throws IOException {
  769. Enumeration[] tmp = new Enumeration[2];
  770. if (parent != null) {
  771. tmp[0] = parent.getResources(name);
  772. } else {
  773. tmp[0] = getBootstrapResources(name);
  774. }
  775. tmp[1] = findResources(name);
  776. return new CompoundEnumeration(tmp);
  777. }
  778. /**
  779. * Finds the resource with the given name. Class loader implementations
  780. * should override this method to specify where to find resources. </p>
  781. *
  782. * @param name
  783. * The resource name
  784. *
  785. * @return A <tt>URL</tt> object for reading the resource, or
  786. * <tt>null</tt> if the resource could not be found
  787. *
  788. * @since 1.2
  789. */
  790. protected URL findResource(String name) {
  791. return null;
  792. }
  793. /**
  794. * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
  795. * representing all the resources with the given name. Class loader
  796. * implementations should override this method to specify where to load
  797. * resources from. </p>
  798. *
  799. * @param name
  800. * The resource name
  801. *
  802. * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
  803. * the resources
  804. *
  805. * @throws IOException
  806. * If I/O errors occur
  807. *
  808. * @since 1.2
  809. */
  810. protected Enumeration findResources(String name) throws IOException {
  811. return new CompoundEnumeration(new Enumeration[0]);
  812. }
  813. /**
  814. * Find a resource of the specified name from the search path used to load
  815. * classes. This method locates the resource through the system class
  816. * loader (see {@link #getSystemClassLoader()}). </p>
  817. *
  818. * @param name
  819. * The resource name
  820. *
  821. * @return A {@link java.net.URL <tt>URL</tt>} object for reading the
  822. * resource, or <tt>null</tt> if the resource could not be found
  823. *
  824. * @since 1.1
  825. */
  826. public static URL getSystemResource(String name) {
  827. ClassLoader system = getSystemClassLoader();
  828. if (system == null) {
  829. return getBootstrapResource(name);
  830. }
  831. return system.getResource(name);
  832. }
  833. /**
  834. * Finds all resources of the specified name from the search path used to
  835. * load classes. The resources thus found are returned as an
  836. * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
  837. * java.net.URL <tt>URL</tt>} objects.
  838. *
  839. * <p> The search order is described in the documentation for {@link
  840. * #getSystemResource(String)}. </p>
  841. *
  842. * @param name
  843. * The resource name
  844. *
  845. * @return An enumeration of resource {@link java.net.URL <tt>URL</tt>}
  846. * objects
  847. *
  848. * @throws IOException
  849. * If I/O errors occur
  850. * @since 1.2
  851. */
  852. public static Enumeration getSystemResources(String name)
  853. throws IOException
  854. {
  855. ClassLoader system = getSystemClassLoader();
  856. if (system == null) {
  857. return getBootstrapResources(name);
  858. }
  859. return system.getResources(name);
  860. }
  861. /**
  862. * Find resources from the VM's built-in classloader.
  863. */
  864. private static URL getBootstrapResource(String name) {
  865. URLClassPath ucp = getBootstrapClassPath();
  866. Resource res = ucp.getResource(name);
  867. return res != null ? res.getURL() : null;
  868. }
  869. /**
  870. * Find resources from the VM's built-in classloader.
  871. */
  872. private static Enumeration getBootstrapResources(String name)
  873. throws IOException
  874. {
  875. final Enumeration e = getBootstrapClassPath().getResources(name);
  876. return new Enumeration () {
  877. public Object nextElement() {
  878. return ((Resource)e.nextElement()).getURL();
  879. }
  880. public boolean hasMoreElements() {
  881. return e.hasMoreElements();
  882. }
  883. };
  884. }
  885. // Returns the URLClassPath that is used for finding system resources.
  886. static URLClassPath getBootstrapClassPath() {
  887. if (bootstrapClassPath == null) {
  888. bootstrapClassPath = sun.misc.Launcher.getBootstrapClassPath();
  889. }
  890. return bootstrapClassPath;
  891. }
  892. private static URLClassPath bootstrapClassPath;
  893. /**
  894. * Returns an input stream for reading the specified resource.
  895. *
  896. * <p> The search order is described in the documentation for {@link
  897. * #getResource(String)}. </p>
  898. *
  899. * @param name
  900. * The resource name
  901. *
  902. * @return An input stream for reading the resource, or <tt>null</tt>
  903. * if the resource could not be found
  904. *
  905. * @since 1.1
  906. */
  907. public InputStream getResourceAsStream(String name) {
  908. URL url = getResource(name);
  909. try {
  910. return url != null ? url.openStream() : null;
  911. } catch (IOException e) {
  912. return null;
  913. }
  914. }
  915. /**
  916. * Open for reading, a resource of the specified name from the search path
  917. * used to load classes. This method locates the resource through the
  918. * system class loader (see {@link #getSystemClassLoader()}). </p>
  919. *
  920. * @param name
  921. * The resource name
  922. *
  923. * @return An input stream for reading the resource, or <tt>null</tt>
  924. * if the resource could not be found
  925. *
  926. * @since 1.1
  927. */
  928. public static InputStream getSystemResourceAsStream(String name) {
  929. URL url = getSystemResource(name);
  930. try {
  931. return url != null ? url.openStream() : null;
  932. } catch (IOException e) {
  933. return null;
  934. }
  935. }
  936. // -- Hierarchy --
  937. /**
  938. * Returns the parent class loader for delegation. Some implementations may
  939. * use <tt>null</tt> to represent the bootstrap class loader. This method
  940. * will return <tt>null</tt> in such implementations if this class loader's
  941. * parent is the bootstrap class loader.
  942. *
  943. * <p> If a security manager is present, and the invoker's class loader is
  944. * not <tt>null</tt> and is not an ancestor of this class loader, then this
  945. * method invokes the security manager's {@link
  946. * SecurityManager#checkPermission(java.security.Permission)
  947. * <tt>checkPermission</tt>} method with a {@link
  948. * RuntimePermission#RuntimePermission(String)
  949. * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
  950. * access to the parent class loader is permitted. If not, a
  951. * <tt>SecurityException</tt> will be thrown. </p>
  952. *
  953. * @return The parent <tt>ClassLoader</tt>
  954. *
  955. * @throws SecurityException
  956. * If a security manager exists and its <tt>checkPermission</tt>
  957. * method doesn't allow access to this class loader's parent class
  958. * loader.
  959. *
  960. * @since 1.2
  961. */
  962. public final ClassLoader getParent() {
  963. if (parent == null)
  964. return null;
  965. SecurityManager sm = System.getSecurityManager();
  966. if (sm != null) {
  967. ClassLoader ccl = getCallerClassLoader();
  968. if (ccl != null && !isAncestor(ccl)) {
  969. sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
  970. }
  971. }
  972. return parent;
  973. }
  974. /**
  975. * Returns the system class loader for delegation. This is the default
  976. * delegation parent for new <tt>ClassLoader</tt> instances, and is
  977. * typically the class loader used to start the application.
  978. *
  979. * <p> This method is first invoked early in the runtime's startup
  980. * sequence, at which point it creates the system class loader and sets it
  981. * as the context class loader of the invoking <tt>Thread</tt>.
  982. *
  983. * <p> The default system class loader is an implementation-dependent
  984. * instance of this class.
  985. *
  986. * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
  987. * when this method is first invoked then the value of that property is
  988. * taken to be the name of a class that will be returned as the system
  989. * class loader. The class is loaded using the default system class loader
  990. * and must define a public constructor that takes a single parameter of
  991. * type <tt>ClassLoader</tt> which is used as the delegation parent. An
  992. * instance is then created using this constructor with the default system
  993. * class loader as the parameter. The resulting class loader is defined
  994. * to be the system class loader.
  995. *
  996. * <p> If a security manager is present, and the invoker's class loader is
  997. * not <tt>null</tt> and the invoker's class loader is not the same as or
  998. * an ancestor of the system class loader, then this method invokes the
  999. * security manager's {@link
  1000. * SecurityManager#checkPermission(java.security.Permission)
  1001. * <tt>checkPermission</tt>} method with a {@link
  1002. * RuntimePermission#RuntimePermission(String)
  1003. * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
  1004. * access to the system class loader. If not, a
  1005. * <tt>SecurityException</tt> will be thrown. </p>
  1006. *
  1007. * @return The system <tt>ClassLoader</tt> for delegation, or
  1008. * <tt>null</tt> if none
  1009. *
  1010. * @throws SecurityException
  1011. * If a security manager exists and its <tt>checkPermission</tt>
  1012. * method doesn't allow access to the system class loader.
  1013. *
  1014. * @throws IllegalStateException
  1015. * If invoked recursively during the construction of the class
  1016. * loader specified by the "<tt>java.system.class.loader</tt>"
  1017. * property.
  1018. *
  1019. * @throws Error
  1020. * If the system property "<tt>java.system.class.loader</tt>"
  1021. * is defined but the named class could not be loaded, the
  1022. * provider class does not define the required constructor, or an
  1023. * exception is thrown by that constructor when it is invoked. The
  1024. * underlying cause of the error can be retrieved via the
  1025. * {@link Throwable#getCause()} method.
  1026. *
  1027. * @revised 1.4
  1028. */
  1029. public static ClassLoader getSystemClassLoader() {
  1030. initSystemClassLoader();
  1031. if (scl == null) {
  1032. return null;
  1033. }
  1034. SecurityManager sm = System.getSecurityManager();
  1035. if (sm != null) {
  1036. ClassLoader ccl = getCallerClassLoader();
  1037. if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) {
  1038. sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
  1039. }
  1040. }
  1041. return scl;
  1042. }
  1043. private static synchronized void initSystemClassLoader() {
  1044. if (!sclSet) {
  1045. if (scl != null)
  1046. throw new IllegalStateException("recursive invocation");
  1047. sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
  1048. if (l != null) {
  1049. Throwable oops = null;
  1050. scl = l.getClassLoader();
  1051. try {
  1052. PrivilegedExceptionAction a;
  1053. a = new SystemClassLoaderAction(scl);
  1054. scl = (ClassLoader) AccessController.doPrivileged(a);
  1055. } catch (PrivilegedActionException pae) {
  1056. oops = pae.getCause();
  1057. if (oops instanceof InvocationTargetException) {
  1058. oops = oops.getCause();
  1059. }
  1060. }
  1061. if (oops != null) {
  1062. if (oops instanceof Error) {
  1063. throw (Error) oops;
  1064. } else {
  1065. // wrap the exception
  1066. throw new Error(oops);
  1067. }
  1068. }
  1069. }
  1070. sclSet = true;
  1071. }
  1072. }
  1073. // Returns true if the specified class loader can be found in this class
  1074. // loader's delegation chain.
  1075. boolean isAncestor(ClassLoader cl) {
  1076. ClassLoader acl = this;
  1077. do {
  1078. acl = acl.parent;
  1079. if (cl == acl) {
  1080. return true;
  1081. }
  1082. } while (acl != null);
  1083. return false;
  1084. }
  1085. // Returns the invoker's class loader, or null if none.
  1086. // NOTE: This must always be invoked when there is exactly one intervening
  1087. // frame from the core libraries on the stack between this method's
  1088. // invocation and the desired invoker.
  1089. static ClassLoader getCallerClassLoader() {
  1090. // NOTE use of more generic Reflection.getCallerClass()
  1091. Class caller = Reflection.getCallerClass(3);
  1092. // This can be null if the VM is requesting it
  1093. if (caller == null) {
  1094. return null;
  1095. }
  1096. // Circumvent security check since this is package-private
  1097. return caller.getClassLoader0();
  1098. }
  1099. // The class loader for the system
  1100. private static ClassLoader scl;
  1101. // Set to true once the system class loader has been set
  1102. private static boolean sclSet;
  1103. // -- Package --
  1104. /**
  1105. * Defines a package by name in this <tt>ClassLoader</tt>. This allows
  1106. * class loaders to define the packages for their classes. Packages must
  1107. * be created before the class is defined, and package names must be
  1108. * unique within a class loader and cannot be redefined or changed once
  1109. * created. </p>
  1110. *
  1111. * @param name
  1112. * The package name
  1113. *
  1114. * @param specTitle
  1115. * The specification title
  1116. *
  1117. * @param specVersion
  1118. * The specification version
  1119. *
  1120. * @param specVendor
  1121. * The specification vendor
  1122. *
  1123. * @param implTitle
  1124. * The implementation title
  1125. *
  1126. * @param implVersion
  1127. * The implementation version
  1128. *
  1129. * @param implVendor
  1130. * The implementation vendor
  1131. *
  1132. * @param sealBase
  1133. * If not <tt>null</tt>, then this package is sealed with
  1134. * respect to the given code source {@link java.net.URL
  1135. * <tt>URL</tt>} object. Otherwise, the package is not sealed.
  1136. *
  1137. * @return The newly defined <tt>Package</tt> object
  1138. *
  1139. * @throws IllegalArgumentException
  1140. * If package name duplicates an existing package either in this
  1141. * class loader or one of its ancestors
  1142. *
  1143. * @since 1.2
  1144. */
  1145. protected Package definePackage(String name, String specTitle,
  1146. String specVersion, String specVendor,
  1147. String implTitle, String implVersion,
  1148. String implVendor, URL sealBase)
  1149. throws IllegalArgumentException
  1150. {
  1151. synchronized (packages) {
  1152. Package pkg = getPackage(name);
  1153. if (pkg != null) {
  1154. throw new IllegalArgumentException(name);
  1155. }
  1156. pkg = new Package(name, specTitle, specVersion, specVendor,
  1157. implTitle, implVersion, implVendor,
  1158. sealBase);
  1159. packages.put(name, pkg);
  1160. return pkg;
  1161. }
  1162. }
  1163. /**
  1164. * Returns a <tt>Package</tt> that has been defined by this class loader
  1165. * or any of its ancestors. </p>
  1166. *
  1167. * @param name
  1168. * The package name
  1169. *
  1170. * @return The <tt>Package</tt> corresponding to the given name, or
  1171. * <tt>null</tt> if not found
  1172. *
  1173. * @since 1.2
  1174. */
  1175. protected Package getPackage(String name) {
  1176. synchronized (packages) {
  1177. Package pkg = (Package)packages.get(name);
  1178. if (pkg == null) {
  1179. if (parent != null) {
  1180. pkg = parent.getPackage(name);
  1181. } else {
  1182. pkg = Package.getSystemPackage(name);
  1183. }
  1184. if (pkg != null) {
  1185. packages.put(name, pkg);
  1186. }
  1187. }
  1188. return pkg;
  1189. }
  1190. }
  1191. /**
  1192. * Returns all of the <tt>Packages</tt> defined by this class loader and
  1193. * its ancestors. </p>
  1194. *
  1195. * @return The array of <tt>Package</tt> objects defined by this
  1196. * <tt>ClassLoader</tt>
  1197. *
  1198. * @since 1.2
  1199. */
  1200. protected Package[] getPackages() {
  1201. Map map;
  1202. synchronized (packages) {
  1203. map = (Map)packages.clone();
  1204. }
  1205. Package[] pkgs;
  1206. if (parent != null) {
  1207. pkgs = parent.getPackages();
  1208. } else {
  1209. pkgs = Package.getSystemPackages();
  1210. }
  1211. if (pkgs != null) {
  1212. for (int i = 0; i < pkgs.length; i++) {
  1213. String pkgName = pkgs[i].getName();
  1214. if (map.get(pkgName) == null) {
  1215. map.put(pkgName, pkgs[i]);
  1216. }
  1217. }
  1218. }
  1219. return (Package[])map.values().toArray(new Package[map.size()]);
  1220. }
  1221. // -- Native library access --
  1222. /**
  1223. * Returns the absolute path name of a native library. The VM invokes this
  1224. * method to locate the native libraries that belong to classes loaded with
  1225. * this class loader. If this method returns <tt>null</tt>, the VM
  1226. * searches the library along the path specified as the
  1227. * "<tt>java.library.path</tt>" property. </p>
  1228. *
  1229. * @param libname
  1230. * The library name
  1231. *
  1232. * @return The absolute path of the native library
  1233. *
  1234. * @see System#loadLibrary(String)
  1235. * @see System#mapLibraryName(String)
  1236. *
  1237. * @since 1.2
  1238. */
  1239. protected String findLibrary(String libname) {
  1240. return null;
  1241. }
  1242. /**
  1243. * The inner class NativeLibrary denotes a loaded native library instance.
  1244. * Every classloader contains a vector of loaded native libraries in the
  1245. * private field <tt>nativeLibraries</tt>. The native libraries loaded
  1246. * into the system are entered into the <tt>systemNativeLibraries</tt>
  1247. * vector.
  1248. *
  1249. * <p> Every native library reuqires a particular version of JNI. This is
  1250. * denoted by the private <tt>jniVersion</tt> field. This field is set by
  1251. * the VM when it loads the library, and used by the VM to pass the correct
  1252. * version of JNI to the native methods. </p>
  1253. *
  1254. * @version 1.169 01/23/03
  1255. * @see ClassLoader
  1256. * @since 1.2
  1257. */
  1258. static class NativeLibrary {
  1259. // opaque handle to native library, used in native code.
  1260. long handle;
  1261. // the version of JNI environment the native library requires.
  1262. private int jniVersion;
  1263. // the class from which the library is loaded, also indicates
  1264. // the loader this native library belongs.
  1265. private Class fromClass;
  1266. // the canonicalized name of the native library.
  1267. String name;
  1268. native void load(String name);
  1269. native long find(String name);
  1270. native void unload();
  1271. public NativeLibrary(Class fromClass, String name) {
  1272. this.name = name;
  1273. this.fromClass = fromClass;
  1274. }
  1275. protected void finalize() {
  1276. synchronized (loadedLibraryNames) {
  1277. if (fromClass.getClassLoader() != null && handle != 0) {
  1278. /* remove the native library name */
  1279. int size = loadedLibraryNames.size();
  1280. for (int i = 0; i < size; i++) {
  1281. if (name.equals(loadedLibraryNames.elementAt(i))) {
  1282. loadedLibraryNames.removeElementAt(i);
  1283. break;
  1284. }
  1285. }
  1286. /* unload the library. */
  1287. ClassLoader.nativeLibraryContext.push(this);
  1288. try {
  1289. unload();
  1290. } finally {
  1291. ClassLoader.nativeLibraryContext.pop();
  1292. }
  1293. }
  1294. }
  1295. }
  1296. // Invoked in the VM to determine the context class in
  1297. // JNI_Load/JNI_Unload
  1298. static Class getFromClass() {
  1299. return ((NativeLibrary)
  1300. (ClassLoader.nativeLibraryContext.peek())).fromClass;
  1301. }
  1302. }
  1303. // The "default" domain. Set as the default ProtectionDomain on newly
  1304. // created classses.
  1305. private ProtectionDomain defaultDomain = null;
  1306. // Returns (and initializes) the default domain.
  1307. private synchronized ProtectionDomain getDefaultDomain() {
  1308. if (defaultDomain == null) {
  1309. CodeSource cs = new CodeSource(null, null);
  1310. defaultDomain = new ProtectionDomain(cs, null, this, null);
  1311. }
  1312. return defaultDomain;
  1313. }
  1314. // All native library names we've loaded.
  1315. private static Vector loadedLibraryNames = new Vector();
  1316. // Native libraries belonging to system classes.
  1317. private static Vector systemNativeLibraries = new Vector();
  1318. // Native libraries associated with the class loader.
  1319. private Vector nativeLibraries = new Vector();
  1320. // native libraries being loaded/unloaded.
  1321. private static Stack nativeLibraryContext = new Stack();
  1322. // The paths searched for libraries
  1323. static private String usr_paths[];
  1324. static private String sys_paths[];
  1325. private static String[] initializePath(String propname) {
  1326. String ldpath = System.getProperty(propname, "");
  1327. String ps = File.pathSeparator;
  1328. int ldlen = ldpath.length();
  1329. int i, j, n;
  1330. // Count the separators in the path
  1331. i = ldpath.indexOf(ps);
  1332. n = 0;
  1333. while (i >= 0) {
  1334. n++;
  1335. i = ldpath.indexOf(ps, i + 1);
  1336. }
  1337. // allocate the array of paths - n :'s = n + 1 path elements
  1338. String[] paths = new String[n + 1];
  1339. // Fill the array with paths from the ldpath
  1340. n = i = 0;
  1341. j = ldpath.indexOf(ps);
  1342. while (j >= 0) {
  1343. if (j - i > 0) {
  1344. paths[n++] = ldpath.substring(i, j);
  1345. } else if (j - i == 0) {
  1346. paths[n++] = ".";
  1347. }
  1348. i = j + 1;
  1349. j = ldpath.indexOf(ps, i);
  1350. }
  1351. paths[n] = ldpath.substring(i, ldlen);
  1352. return paths;
  1353. }
  1354. // Invoked in the java.lang.Runtime class to implement load and loadLibrary.
  1355. static void loadLibrary(Class fromClass, String name,
  1356. boolean isAbsolute) {
  1357. ClassLoader loader =
  1358. (fromClass == null) ? null : fromClass.getClassLoader();
  1359. if (sys_paths == null) {
  1360. usr_paths = initializePath("java.library.path");
  1361. sys_paths = initializePath("sun.boot.library.path");
  1362. }
  1363. if (isAbsolute) {
  1364. if (loadLibrary0(fromClass, new File(name))) {
  1365. return;
  1366. }
  1367. throw new UnsatisfiedLinkError("Can't load library: " + name);
  1368. }
  1369. if (loader != null) {
  1370. String libfilename = loader.findLibrary(name);
  1371. if (libfilename != null) {
  1372. File libfile = new File(libfilename);
  1373. if (!libfile.isAbsolute()) {
  1374. throw new UnsatisfiedLinkError(
  1375. "ClassLoader.findLibrary failed to return an absolute path: " + libfilename);
  1376. }
  1377. if (loadLibrary0(fromClass, libfile)) {
  1378. return;
  1379. }
  1380. throw new UnsatisfiedLinkError("Can't load " + libfilename);
  1381. }
  1382. }
  1383. for (int i = 0 ; i < sys_paths.length ; i++) {
  1384. File libfile = new File(sys_paths[i], System.mapLibraryName(name));
  1385. if (loadLibrary0(fromClass, libfile)) {
  1386. return;
  1387. }
  1388. }
  1389. if (loader != null) {
  1390. for (int i = 0 ; i < usr_paths.length ; i++) {
  1391. File libfile = new File(usr_paths[i],
  1392. System.mapLibraryName(name));
  1393. if (loadLibrary0(fromClass, libfile)) {
  1394. return;
  1395. }
  1396. }
  1397. }
  1398. // Oops, it failed
  1399. throw new UnsatisfiedLinkError("no " + name + " in java.library.path");
  1400. }
  1401. private static boolean loadLibrary0(Class fromClass, final File file) {
  1402. Boolean exists = (Boolean)
  1403. AccessController.doPrivileged(new PrivilegedAction() {
  1404. public Object run() {
  1405. return new Boolean(file.exists());
  1406. }
  1407. });
  1408. if (!exists.booleanValue()) {
  1409. return false;
  1410. }
  1411. String name;
  1412. try {
  1413. name = file.getCanonicalPath();
  1414. } catch (IOException e) {
  1415. return false;
  1416. }
  1417. ClassLoader loader =
  1418. (fromClass == null) ? null : fromClass.getClassLoader();
  1419. Vector libs =
  1420. loader != null ? loader.nativeLibraries : systemNativeLibraries;
  1421. synchronized (libs) {
  1422. int size = libs.size();
  1423. for (int i = 0; i < size; i++) {
  1424. NativeLibrary lib = (NativeLibrary)libs.elementAt(i);
  1425. if (name.equals(lib.name)) {
  1426. return true;
  1427. }
  1428. }
  1429. synchronized (loadedLibraryNames) {
  1430. if (loadedLibraryNames.contains(name)) {
  1431. throw new UnsatisfiedLinkError
  1432. ("Native Library " +
  1433. name +
  1434. " already loaded in another classloader");
  1435. }
  1436. /* If the library is being loaded (must be by the same thread,
  1437. * because Runtime.load and Runtime.loadLibrary are
  1438. * synchronous). The reason is can occur is that the JNI_OnLoad
  1439. * function can cause another loadLibrary invocation.
  1440. *
  1441. * Thus we can use a static stack to hold the list of libraries
  1442. * we are loading.
  1443. *
  1444. * If there is a pending load operation for the library, we
  1445. * immediately return success; otherwise, we raise
  1446. * UnsatisfiedLinkError.
  1447. */
  1448. int n = nativeLibraryContext.size();
  1449. for (int i = 0; i < n; i++) {
  1450. NativeLibrary lib = (NativeLibrary)
  1451. nativeLibraryContext.elementAt(i);
  1452. if (name.equals(lib.name)) {
  1453. if (loader == lib.fromClass.getClassLoader()) {
  1454. return true;
  1455. } else {
  1456. throw new UnsatisfiedLinkError
  1457. ("Native Library " +
  1458. name +
  1459. " is being loaded in another classloader");
  1460. }
  1461. }
  1462. }
  1463. NativeLibrary lib = new NativeLibrary(fromClass, name);
  1464. nativeLibraryContext.push(lib);
  1465. try {
  1466. lib.load(name);
  1467. } finally {
  1468. nativeLibraryContext.pop();
  1469. }
  1470. if (lib.handle != 0) {
  1471. loadedLibraryNames.addElement(name);
  1472. libs.addElement(lib);
  1473. return true;
  1474. }
  1475. return false;
  1476. }
  1477. }
  1478. }
  1479. // Invoked in the VM class linking code.
  1480. static long findNative(ClassLoader loader, String name) {
  1481. Vector libs =
  1482. loader != null ? loader.nativeLibraries : systemNativeLibraries;
  1483. synchronized (libs) {
  1484. int size = libs.size();
  1485. for (int i = 0; i < size; i++) {
  1486. NativeLibrary lib = (NativeLibrary)libs.elementAt(i);
  1487. long entry = lib.find(name);
  1488. if (entry != 0)
  1489. return entry;
  1490. }
  1491. }
  1492. return 0;
  1493. }
  1494. // -- Assertion management --
  1495. // The default toggle for assertion checking.
  1496. private boolean defaultAssertionStatus = false;
  1497. // Maps String packageName to Boolean package default assertion status Note
  1498. // that the default package is placed under a null map key. If this field
  1499. // is null then we are delegating assertion status queries to the VM, i.e.,
  1500. // none of this ClassLoader's assertion status modification methods have
  1501. // been invoked.
  1502. private Map packageAssertionStatus = null;
  1503. // Maps String fullyQualifiedClassName to Boolean assertionStatus If this
  1504. // field is null then we are delegating assertion status queries to the VM,
  1505. // i.e., none of this ClassLoader's assertion status modification methods
  1506. // have been invoked.
  1507. Map classAssertionStatus = null;
  1508. /**
  1509. * Sets the default assertion status for this class loader. This setting
  1510. * determines whether classes loaded by this class loader and initialized
  1511. * in the future will have assertions enabled or disabled by default.
  1512. * This setting may be overridden on a per-package or per-class basis by
  1513. * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link
  1514. * #setClassAssertionStatus(String, boolean)}. </p>
  1515. *
  1516. * @param enabled
  1517. * <tt>true</tt> if classes loaded by this class loader will
  1518. * henceforth have assertions enabled by default, <tt>false</tt>
  1519. * if they will have assertions disabled by default.
  1520. *
  1521. * @since 1.4
  1522. */
  1523. public synchronized void setDefaultAssertionStatus(boolean enabled) {
  1524. if (classAssertionStatus == null)
  1525. initializeJavaAssertionMaps();
  1526. defaultAssertionStatus = enabled;
  1527. }
  1528. /**
  1529. * Sets the package default assertion status for the named package. The
  1530. * package default assertion status determines the assertion status for
  1531. * classes initialized in the future that belong to the named package or
  1532. * any of its "subpackages".
  1533. *
  1534. * <p> A subpackage of a package named p is any package whose name begins
  1535. * with "<tt>p.</tt>". For example, <tt>javax.swing.text</tt> is a
  1536. * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and
  1537. * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>.
  1538. *
  1539. * <p> In the event that multiple package defaults apply to a given class,
  1540. * the package default pertaining to the most specific package takes
  1541. * precedence over the others. For example, if <tt>javax.lang</tt> and
  1542. * <tt>javax.lang.reflect</tt> both have package defaults associated with
  1543. * them, the latter package default applies to classes in
  1544. * <tt>javax.lang.reflect</tt>.
  1545. *
  1546. * <p> Package defaults take precedence over the class loader's default
  1547. * assertion status, and may be overridden on a per-class basis by invoking
  1548. * {@link #setClassAssertionStatus(String, boolean)}. </p>
  1549. *
  1550. * @param packageName
  1551. * The name of the package whose package default assertion status
  1552. * is to be set. A <tt>null</tt> value indicates the unnamed
  1553. * package that is "current" (<a *
  1554. * href="http://java.sun.com/docs/books/jls/">Java Language
  1555. * Specification</a>, section 7.4.2).
  1556. *
  1557. * @param enabled
  1558. * <tt>true</tt> if classes loaded by this classloader and
  1559. * belonging to the named package or any of its subpackages will
  1560. * have assertions enabled by default, <tt>false</tt> if they will
  1561. * have assertions disabled by default.
  1562. *
  1563. * @since 1.4
  1564. */
  1565. public synchronized void setPackageAssertionStatus(String packageName,
  1566. boolean enabled)
  1567. {
  1568. if (packageAssertionStatus == null)
  1569. initializeJavaAssertionMaps();
  1570. packageAssertionStatus.put(packageName, Boolean.valueOf(enabled));
  1571. }
  1572. /**
  1573. * Sets the desired assertion status for the named top-level class in this
  1574. * class loader and any nested classes contained therein. This setting
  1575. * takes precedence over the class loader's default assertion status, and
  1576. * over any applicable per-package default. This method has no effect if
  1577. * the named class has already been initialized. (Once a class is
  1578. * initialized, its assertion status cannot change.)
  1579. *
  1580. * <p> If the named class is not a top-level class, this invocation will
  1581. * have no effect on the actual assertion status of any class, and its
  1582. * return value is undefined. </p>
  1583. *
  1584. * @param className
  1585. * The fully qualified class name of the top-level class whose
  1586. * assertion status is to be set.
  1587. *
  1588. * @param enabled
  1589. * <tt>true</tt> if the named class is to have assertions
  1590. * enabled when (and if) it is initialized, <tt>false</tt> if the
  1591. * class is to have assertions disabled.
  1592. *
  1593. * @since 1.4
  1594. */
  1595. public synchronized void setClassAssertionStatus(String className,
  1596. boolean enabled)
  1597. {
  1598. if (classAssertionStatus == null)
  1599. initializeJavaAssertionMaps();
  1600. classAssertionStatus.put(className, Boolean.valueOf(enabled));
  1601. }
  1602. /**
  1603. * Sets the default assertion status for this class loader to
  1604. * <tt>false</tt> and discards any package defaults or class assertion
  1605. * status settings associated with the class loader. This method is
  1606. * provided so that class loaders can be made to ignore any command line or
  1607. * persistent assertion status settings and "start with a clean slate."
  1608. * </p>
  1609. *
  1610. * @since 1.4
  1611. */
  1612. public synchronized void clearAssertionStatus() {
  1613. /*
  1614. * Whether or not "Java assertion maps" are initialized, set
  1615. * them to empty maps, effectively ignoring any present settings.
  1616. */
  1617. classAssertionStatus = new HashMap();
  1618. packageAssertionStatus = new HashMap();
  1619. defaultAssertionStatus = false;
  1620. }
  1621. /**
  1622. * Returns the assertion status that would be assigned to the specified
  1623. * class if it were to be initialized at the time this method is invoked.
  1624. * If the named class has had its assertion status set, the most recent
  1625. * setting will be returned; otherwise, if any package default assertion
  1626. * status pertains to this class, the most recent setting for the most
  1627. * specific pertinent package default assertion status is returned;
  1628. * otherwise, this class loader's default assertion status is returned.
  1629. * </p>
  1630. *
  1631. * @param className
  1632. * The fully qualified class name of the class whose desired
  1633. * assertion status is being queried.
  1634. *
  1635. * @return The desired assertion status of the specified class.
  1636. *
  1637. * @see #setClassAssertionStatus(String, boolean)
  1638. * @see #setPackageAssertionStatus(String, boolean)
  1639. * @see #setDefaultAssertionStatus(boolean)
  1640. *
  1641. * @since 1.4
  1642. */
  1643. synchronized boolean desiredAssertionStatus(String className) {
  1644. Boolean result;
  1645. // assert classAssertionStatus != null;
  1646. // assert packageAssertionStatus != null;
  1647. // Check for a class entry
  1648. result = (Boolean)classAssertionStatus.get(className);
  1649. if (result != null)
  1650. return result.booleanValue();
  1651. // Check for most specific package entry
  1652. int dotIndex = className.lastIndexOf(".");
  1653. if (dotIndex < 0) { // default package
  1654. result = (Boolean)packageAssertionStatus.get(null);
  1655. if (result != null)
  1656. return result.booleanValue();
  1657. }
  1658. while(dotIndex > 0) {
  1659. className = className.substring(0, dotIndex);
  1660. result = (Boolean)packageAssertionStatus.get(className);
  1661. if (result != null)
  1662. return result.booleanValue();
  1663. dotIndex = className.lastIndexOf(".", dotIndex-1);
  1664. }
  1665. // Return the classloader default
  1666. return defaultAssertionStatus;
  1667. }
  1668. // Set up the assertions with information provided by the VM.
  1669. private void initializeJavaAssertionMaps() {
  1670. // assert Thread.holdsLock(this);
  1671. classAssertionStatus = new HashMap();
  1672. packageAssertionStatus = new HashMap();
  1673. AssertionStatusDirectives directives = retrieveDirectives();
  1674. for(int i = 0; i < directives.classes.length; i++)
  1675. classAssertionStatus.put(directives.classes[i],
  1676. Boolean.valueOf(directives.classEnabled[i]));
  1677. for(int i = 0; i < directives.packages.length; i++)
  1678. packageAssertionStatus.put(directives.packages[i],
  1679. Boolean.valueOf(directives.packageEnabled[i]));
  1680. defaultAssertionStatus = directives.deflt;
  1681. }
  1682. // Retrieves the assertion directives from the VM.
  1683. private static native AssertionStatusDirectives retrieveDirectives();
  1684. }
  1685. class SystemClassLoaderAction implements PrivilegedExceptionAction {
  1686. private ClassLoader parent;
  1687. SystemClassLoaderAction(ClassLoader parent) {
  1688. this.parent = parent;
  1689. }
  1690. public Object run() throws Exception {
  1691. ClassLoader sys;
  1692. Constructor ctor;
  1693. Class c;
  1694. Class cp[] = { ClassLoader.class };
  1695. Object params[] = { parent };
  1696. String cls = System.getProperty("java.system.class.loader");
  1697. if (cls == null) {
  1698. return parent;
  1699. }
  1700. c = Class.forName(cls, true, parent);
  1701. ctor = c.getDeclaredConstructor(cp);
  1702. sys = (ClassLoader) ctor.newInstance(params);
  1703. Thread.currentThread().setContextClassLoader(sys);
  1704. return sys;
  1705. }
  1706. }