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