home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / lang / ClassLoader.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  32.7 KB  |  980 lines

  1. /*
  2.  * @(#)ClassLoader.java    1.91 98/03/18
  3.  *
  4.  * Copyright 1994-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.lang;
  16.  
  17. import java.io.InputStream;
  18. import java.io.IOException;
  19. import java.io.StringWriter;
  20. import java.io.PrintWriter;
  21. import java.util.Hashtable;
  22. import java.util.Enumeration;
  23. import java.util.Vector;
  24. import java.util.Stack;
  25. import java.util.NoSuchElementException;
  26. import java.net.URL;
  27. import java.net.MalformedURLException;
  28. import java.security.AccessController;
  29. import java.security.ProtectionDomain;
  30. import java.security.CodeSource;
  31. import java.security.Policy;
  32. import sun.misc.URLClassPath;
  33. import sun.misc.Resource;
  34. import sun.misc.CompoundEnumeration;
  35. import sun.misc.Launcher;
  36.  
  37. /**
  38.  * The class <code>ClassLoader</code> is an abstract class. 
  39.  * Applications implement subclasses of <code>ClassLoader</code> in 
  40.  * order to extend the manner in which the Java Virtual Machine 
  41.  * dynamically loads classes. 
  42.  * <p>
  43.  * Normally, the Java Virtual Machine loads classes from the local 
  44.  * file system in a platform-dependent manner. For example, on UNIX 
  45.  * systems, the Virtual Machine loads classes from the directory 
  46.  * defined by the <code>CLASSPATH</code> environment variable. 
  47.  * <p>
  48.  * However, some classes may not originate from a file; they may 
  49.  * originate from other sources, such as the network, or they could 
  50.  * be constructed by an application. The method 
  51.  * <code>defineClass</code> converts an array of bytes into an 
  52.  * instance of class <code>Class</code>. Instances of this newly 
  53.  * defined class can be created using the <code>newInstance</code> 
  54.  * method in class <code>Class</code>. 
  55.  * <p>
  56.  * The methods and constructors of objects created by a class loader 
  57.  * may reference other classes. To determine the class(es) referred 
  58.  * to, the Java Virtual Machine calls the <code>loadClass</code> 
  59.  * method of the class loader that originally created the class. If 
  60.  * the Java Virtual Machine only needs to determine if the class 
  61.  * exists and if it does exist to know its superclass, the 
  62.  * <code>resolve</code> flag is set to <code>false</code>. However, 
  63.  * if an instance of the class is being created or any of its methods 
  64.  * are being called, the class must also be resolved. In this case 
  65.  * the <code>resolve</code> flag is set to <code>true</code>, and the 
  66.  * <code>resolveClass</code> method should be called. 
  67.  * <p>
  68.  * For example, an application could create a network class loader 
  69.  * to download class files from a server. Sample code might look like:
  70.  * <blockquote><pre>
  71.  *   ClassLoader loader = new NetworkClassLoader(host, port);
  72.  *   Object main = loader.loadClass("Main", true).newInstance();
  73.  *      . . .
  74.  * </pre></blockquote>
  75.  * <p>
  76.  * The network class loader subclass must define the method 
  77.  * <code>loadClass</code> to load a class from the network. Once it 
  78.  * has downloaded the bytes that make up the class, it should use the 
  79.  * method <code>defineClass</code> to create a class instance. A 
  80.  * sample implementation is: 
  81.  * <p><hr><blockquote><pre>
  82.  *     class NetworkClassLoader extends ClassLoader {
  83.  *         String host;
  84.  *         int port;
  85.  *
  86.  *         public Class findLocalClass(String name) {
  87.  *             byte[] b = loadClassData(name);
  88.  *             return defineClass(name, b, 0, b.length);
  89.  *         }
  90.  *
  91.  *         private byte[] loadClassData(String name) {
  92.  *             // load the class data from the connection
  93.  *              . . .
  94.  *         }
  95.  *     }
  96.  * </pre></blockquote><hr>
  97.  *
  98.  * @version 1.91, 03/18/98
  99.  * @see     java.lang.Class
  100.  * @see     java.lang.Class#newInstance()
  101.  * @see     java.lang.ClassLoader#defineClass(byte[], int, int)
  102.  * @see     java.lang.ClassLoader#loadClass(java.lang.String, boolean)
  103.  * @see     java.lang.ClassLoader#resolveClass(java.lang.Class)
  104.  * @since   JDK1.0
  105.  */
  106. public abstract class ClassLoader {
  107.     /*
  108.      * If initialization succeed this is set to true and security checks will
  109.      * succeed. Otherwise the object is not initialized and the object is
  110.      * useless.
  111.      */
  112.     private boolean initialized = false;
  113.  
  114.     /*
  115.      * The parent class loader for delegation.
  116.      */
  117.     private ClassLoader parent;
  118.  
  119.     /*
  120.      * The classes loaded by this class loader. Each class name is mapped
  121.      * to its corresponding Class object.
  122.      */
  123.     private Hashtable classes = new Hashtable();
  124.  
  125.     /*
  126.      * The packages defined in this class loader. Each package name is
  127.      * mapped to its corresponding Package object.
  128.      */
  129.     private Hashtable packages = new Hashtable();
  130.  
  131.     /**
  132.      * Creates a new class loader using the specified parent class loader
  133.      * for delegation.
  134.      * <p>
  135.      * If there is a security manager, its <code>checkCreateClassLoader</code>
  136.      * method is called. This may result in a security exception. 
  137.      *
  138.      * @exception SecurityException if the current thread does not have
  139.      *            permission to create a new class loader
  140.      * @see       java.lang.SecurityException
  141.      * @see       java.lang.SecurityManager#checkCreateClassLoader()
  142.      * @since     JDK1.2
  143.      */
  144.     protected ClassLoader(ClassLoader parent) {
  145.     SecurityManager security = System.getSecurityManager();
  146.     if (security != null) {
  147.         security.checkCreateClassLoader();
  148.     }
  149.     this.parent = parent;
  150.     initialized = true;
  151.     }
  152.  
  153.     /**
  154.      * Creates a new class loader using the <code>ClassLoader</code>
  155.      * returned by the method <code>getBaseClassLoader()</code> as the
  156.      * parent class loader.
  157.      * <p>
  158.      * If there is a security manager, its <code>checkCreateClassLoader</code>
  159.      * method is called. This may result in a security exception. 
  160.      *
  161.      * @exception SecurityException if the current thread does not have
  162.      *            permission to create a new class loader
  163.      * @see       java.lang.SecurityException
  164.      * @see       java.lang.SecurityManager#checkCreateClassLoader()
  165.      */
  166.     protected ClassLoader() {
  167.     this(getBaseClassLoader());
  168.     }
  169.  
  170.     /**
  171.      * Loads the class with the specified name. The <code>resolveClass</code>
  172.      * method will be called on the resulting <code>Class</code> object.
  173.      *
  174.      * @param     name the name of the class
  175.      * @return    the resulting <code>Class</code> object
  176.      * @see      #resolveClass
  177.      * @exception ClassNotFoundException if the class was not found
  178.      */
  179.     public Class loadClass(String name) throws ClassNotFoundException
  180.     {
  181.     return loadClass(name, true);
  182.     }
  183.  
  184.     /**
  185.      * Loads the class with the specified name. The <code>loadClass</code>
  186.      * method is called by the Java Virtual Machine when a class loaded by
  187.      * a class loader first references another class. The default
  188.      * implementation of <code>loadClass</code> will search for classes in
  189.      * the following order:
  190.      * <ol>
  191.      * <li> Call <code>findLoadedClass</code> to check if the class has
  192.      *      already been loaded.
  193.      * <p>
  194.      * <li> Call the <code>loadClass</code> method of the parent class
  195.      *      loader to load the class, or <code>findSystemClass</code>
  196.      *      if no parent class loader was specified.
  197.      * <p>
  198.      * <li> Call the <code>findLocalClass</code> method to find the class
  199.      *      locally.
  200.      * </ol>
  201.      * If the class was found using the above steps, and the
  202.      * <code>resolve</code> flag is true, this method will then call 
  203.      * the <code>resolveClass</code> method on the resulting class object.
  204.      * <p>
  205.      * Class loader implementations that use the new delegation model
  206.      * introduced in 1.2 should override the <code>findLocalClass</code>
  207.      * method rather than <code>loadClass</code>.
  208.      *
  209.      * @param     name the name of the class
  210.      * @param     resolve if <code>true</code> then resolve the class
  211.      * @return      the resulting <code>Class</code> object
  212.      * @exception ClassNotFoundException if the class could not be found
  213.      */
  214.     protected synchronized Class loadClass(String name, boolean resolve)
  215.     throws ClassNotFoundException
  216.     {
  217.     // First, check if the class has already been loaded
  218.     Class c = findLoadedClass(name);
  219.     if (c == null) {
  220.         // Make sure that we are allowed to load the class
  221.         int i = name.lastIndexOf('.');
  222.         if (i != -1) {
  223.         checkPackageAccess(name.substring(0, i));
  224.         }
  225.         try {
  226.         if (parent != null) {
  227.             c = parent.loadClass(name, false);
  228.         } else {
  229.             c = findSystemClass(name);
  230.         }
  231.         } catch (ClassNotFoundException e) {
  232.         // Stop here if an error actually occurred while trying
  233.         // to load the class.
  234.         if (e.getException() != null) {
  235.             throw e;
  236.         }
  237.         }
  238.         if (c == null) {
  239.         // If still not found, then call findLocalClass in order
  240.         // to find the class locally.
  241.         c = findLocalClass(name);
  242.         }
  243.     }
  244.     if (resolve) {
  245.         resolveClass(c);
  246.     }
  247.     return c;
  248.     }
  249.  
  250.     /**
  251.      * This method can be overridden to throw a <code>SecurityException</code>
  252.      * if the calling thread is not allowed to access the package specified
  253.      * by the argument. By default, the calling thread is allowed to access
  254.      * any package.
  255.      * <p>
  256.      * For example, in order to perform this check using the current
  257.      * <code>SecurityManager</code>:
  258.      * <pre>
  259.      *        SecurityManager sm = System.getSecurityManager();
  260.      *        if (sm != null) {
  261.      *            sm.checkPackageAccess(name.substring(0, i));
  262.      *      }
  263.      * </pre>
  264.      *
  265.      * @param name the package name
  266.      * @exception SecurityException if the caller cannot access the specified
  267.      *            package
  268.      * @since JDK1.2
  269.      */
  270.     protected void checkPackageAccess(String name) throws SecurityException {
  271.     }
  272.  
  273.     /**
  274.      * Finds the specified class locally. This method should be overridden
  275.      * by class loader implementations that follow the new delegation model
  276.      * for loading classes, and will be called by the <code>loadClass</code>
  277.      * method after checking the parent class loader for the requested class.
  278.      * The default implementation throws <code>ClassNotFoundException</code>.
  279.      *
  280.      * @param  name the name of the class
  281.      * @return the resulting <code>Class</code> object
  282.      * @exception ClassNotFoundException if the class could not be found
  283.      * @since  JDK1.2
  284.      */
  285.     protected Class findLocalClass(String name) throws ClassNotFoundException {
  286.     throw new ClassNotFoundException(name);
  287.     }
  288.  
  289.     /** 
  290.      * Converts an array of bytes into an instance of class
  291.      * <code>Class</code>.  Before the Class can be used it must be
  292.      * resolved. This method is deprecated in favor of the version
  293.      * that takes the class name as its first argument, and is more
  294.      * secure.
  295.      *
  296.      * @param      b   the bytes that make up the class data
  297.      * @param      off the start offset of the class data
  298.      * @param      len the length of the class data
  299.      * @return     the <code>Class</code> object that was created from the
  300.      *             specified class data
  301.      * @exception  ClassFormatError if the data did not contain a valid class
  302.      * @see        ClassLoader#loadClass(java.lang.String, boolean)
  303.      * @see        ClassLoader#resolveClass(java.lang.Class)
  304.      * @deprecated Replaced by defineClass(java.lang.String, byte[], int, int) 
  305.      */
  306.     protected final Class defineClass(byte[] b, int off, int len)
  307.     throws ClassFormatError
  308.     { 
  309.     return defineClass(null, b, off, len);
  310.     }
  311.  
  312.     /**
  313.      * Converts an array of bytes into an instance of class <code>Class</code>.
  314.      * Before the Class can be used it must be resolved.
  315.      * <p>
  316.      * This method assigns a default <code>ProtectionDomain</code> to 
  317.      * the newly defined class. The <code>ProtectionDomain</code> 
  318.      * contains the set of permissions granted when
  319.      * a call to <code>Policy.getPolicy().evaluate()</code> is made with a 
  320.      * Codesource of <code>null,null</code>. The default domain is 
  321.      * created on the first invocation of <code>defineClass</code>, and
  322.      * re-used on subsequent calls.
  323.      * <p>
  324.      * Note: There is a similar <code>defineClass</code> method in
  325.      * <code>java.security.SecureClassLoader</code> (a ClassLoader 
  326.      * subclass) that assigns the new class to a passed-in 
  327.      * <code>ProtectionDomain</code>. Also, a class can be assigned to
  328.      * a new <code>ProtectionDomain</code> (one with different permissions) 
  329.      * by a call to the <code>java.lang.Class setProtectionDomain</code>  
  330.      * method, if the caller has permission to
  331.      * reset the domain.
  332.      *
  333.      * @param       name the expected name of the class, or <code>null</code>
  334.      *                  if not known, using '.' and not '/' as the separator
  335.      *                  and without a trailing ".class" suffix.
  336.      * @param      b    the bytes that make up the class data
  337.      * @param      off  the start offset of the class data
  338.      * @param      len  the length of the class data
  339.      * @return     the <code>Class</code> object that was created from the
  340.      *             specified class data
  341.      * @exception  ClassFormatError if the data did not contain a valid class
  342.      * @see        ClassLoader#loadClass(java.lang.String, boolean)
  343.      * @see        ClassLoader#resolveClass(java.lang.Class)
  344.      * @see        java.security.ProtectionDomain
  345.      * @see        java.security.Policy
  346.      * @see        java.security.CodeSource
  347.      * @see        java.security.SecureClassLoader
  348.      * @since      JDK1.1
  349.      */
  350.     protected final Class defineClass(String name, byte[] b, int off, int len)
  351.     throws ClassFormatError
  352.     { 
  353.     check();
  354.     Class c = defineClass0(name, b, off, len);
  355.     if (c != null) {
  356.         classes.put(c.getName(), c);
  357.         c.setProtectionDomain0(getDefaultDomain());
  358.     }
  359.     return c;
  360.     }
  361.  
  362.     /**
  363.      * Resolves the class so that an instance of the class can be created,
  364.      * or so that one of its methods can be called. This method will be
  365.      * called by <code>loadClass</code> if the resolve flag is 
  366.      * <code>true</code>. 
  367.      *
  368.      * @param c the class to be resolved
  369.      * @see   java.lang.ClassLoader#defineClass(java.lang.String,byte[],int,int)
  370.      */
  371.     protected final void resolveClass(Class c) { 
  372.     check();
  373.     resolveClass0(c);
  374.     }
  375.  
  376.     /**
  377.      * Finds the system class with the specified name, loading it in if 
  378.      * necessary. 
  379.      * <p>
  380.      * A system class is a class loaded from the local file system in a 
  381.      * platform-dependent manner, and has no associated class loader. 
  382.      *
  383.      * @param     name the name of the system class
  384.      * @return    a system class with the given name
  385.      * @exception ClassNotFoundException if the class could not be found
  386.      */
  387.     protected final Class findSystemClass(String name)
  388.     throws ClassNotFoundException
  389.     {
  390.     check();
  391.     return findSystemClass0(name);
  392.     }
  393.  
  394.     /**
  395.      * Returns the parent class loader for delegation, or <code>null</code>
  396.      * if none, in which case <code>ClassLoader</code> will delegate to the
  397.      * system class loader.
  398.      *
  399.      * @exception SecurityException if the caller does not have
  400.      *            <code>RuntimePermission("getClassLoader")</code> permission
  401.      * @since JDK1.2
  402.      */
  403.     public ClassLoader getParent() {
  404.     SecurityManager sm = System.getSecurityManager();
  405.     if (sm != null) {
  406.         sm.checkPermission(getClassLoaderPerm);
  407.     }
  408.     return parent;
  409.     }
  410.  
  411.     /**
  412.      * Sets the signers of a class. This should be called after defining a
  413.      * class.
  414.      * @param c the <code>Class</code> object
  415.      * @param signers the signers for the class
  416.      * @since JDK1.1
  417.      */
  418.     protected final void setSigners(Class c, Object[] signers) {
  419.         check();
  420.     c.setSigners(signers);
  421.     }
  422.  
  423.     private native Class defineClass0(String name, byte[] b, int off, int len);
  424.     private native void resolveClass0(Class c);
  425.     private native Class findSystemClass0(String name)
  426.     throws ClassNotFoundException;
  427.  
  428.     /*
  429.      * Check to make sure the class loader has been initialized.
  430.      */
  431.     private void check() { 
  432.     if (!initialized) {
  433.         throw new SecurityException("ClassLoader object not initialized");
  434.     }
  435.     }
  436.  
  437.     /**
  438.      * Finds the class with the given name if it had been previously loaded
  439.      * through this class loader.
  440.      *
  441.      * @param  name the class name
  442.      * @return the <code>Class</object> object, or <code>null</code> if
  443.      *         the class has not been loaded
  444.      * @since  JDK1.1
  445.      */
  446.     protected final Class findLoadedClass(String name) { 
  447.     return (Class)classes.get(name);
  448.     }
  449.  
  450.     /*
  451.      * Called directly by the Virtual Machine to load and resolve a class.
  452.      */
  453.     final Class loadClassInternal(String name, boolean resolve) 
  454.     throws ClassNotFoundException
  455.     {
  456.     name = name.replace('/', '.');
  457.     Class c = (Class)classes.get(name);
  458.     if (c == null) {
  459.         c = loadClass(name, false);
  460.         if (c == null) {
  461.         throw new ClassNotFoundException(name);
  462.         }
  463.         // Is the following still necessary now that defineClass
  464.         // also performs the same check?
  465.         if (!name.equals(c.getName())) {
  466.         throw new ClassNotFoundException(name);
  467.         }
  468.         classes.put(name, c);
  469.     }
  470.     if (resolve) {
  471.         resolveClass(c);
  472.     }
  473.     return c;
  474.     }
  475.  
  476.     /**
  477.      * Finds the resource with the given name. A resource is some data
  478.      * (images, audio, text, etc) that can be accessed by class code
  479.      * in a way that is independent of the location of the code.
  480.      * <p>
  481.      * The name of a resource is a "/"-separated path name that identifies
  482.      * the resource.
  483.      * <p>
  484.      * This method will first search the parent class loader for the
  485.      * resource, then call <code>getLocalResource</code> to find the
  486.      * resource locally.
  487.      *
  488.      * @param  name resource name
  489.      * @return a URL for reading the resource, or <code>null</code> if
  490.      *         the resource could not be found or the caller doesn't have
  491.      *          adequate privileges to get the resource.
  492.      * @since  JDK1.1
  493.      * @see    #getLocalResource
  494.      */
  495.     public URL getResource(String name) {
  496.     URL url;
  497.     if (parent != null) {
  498.         url = parent.getResource(name);
  499.     } else {
  500.         url = getSystemResource(name);
  501.     }
  502.     if (url == null) {
  503.         url = getLocalResource(name);
  504.     }
  505.     return url;
  506.     }
  507.  
  508.     /**
  509.      * Finds all the resources with the given name. A resource is some data
  510.      * (images, audio, text, etc) that can be accessed by class code
  511.      * in a way that is independent of the location of the code.
  512.      * <p>
  513.      * The name of a resource is a "/"-separated path name that identifies
  514.      * the resource.
  515.      * <p>
  516.      * This method will first search the parent class loader for the
  517.      * resource, then call <code>getLocalResource</code> to find the
  518.      * resource locally.
  519.      *
  520.      * @param  name resource name
  521.      * @return an enumeration of URL to the resource. If no resources could
  522.      *         be found, the enumeration will be empty. Resources that the 
  523.      *         doesn't have access to will not be in the enumeration.
  524.      * @since  JDK1.2
  525.      * @see    #getResource
  526.      * @see    #getLocalResources
  527.      */
  528.     public final Enumeration getResources(String name) throws IOException {
  529.     Enumeration[] tmp = new Enumeration[2];
  530.     if (parent != null) {
  531.         tmp[0] = parent.getResources(name);
  532.     } else {
  533.         tmp[0] = getSystemResources(name);
  534.     }
  535.     tmp[1] = getLocalResources(name);
  536.     
  537.     return new CompoundEnumeration(tmp);
  538.     }
  539.  
  540.     /**
  541.      * Returns an Enumeration of URLs representing all the local resources
  542.      * with the given name. Class loader implementations should override this
  543.      * method to load resources from a local source.
  544.      *
  545.      * @param  name the resource name
  546.      * @return an Enumeration of URLs for the local resources
  547.      * @since  JDK1.2
  548.      */
  549.     public Enumeration getLocalResources(String name) throws IOException {
  550.     return new CompoundEnumeration(new Enumeration[0]);
  551.     }
  552.  
  553.     /**
  554.      * Finds the local resource with the given name. Class loader
  555.      * implementations should override this method to load a resource
  556.      * from a local source.
  557.      *
  558.      * @param  name the resource name
  559.      * @return a URL for reading the resource, or <code>null</code>
  560.      *         if the resource could not be found
  561.      * @since  JDK1.2
  562.      */
  563.     public URL getLocalResource(String name) {
  564.     return null;
  565.     }
  566.  
  567.     /**
  568.      * Finds the system resource with the given name. System resources
  569.      * are those loaded from the system class path.
  570.      *
  571.      * @param  name the resource name
  572.      * @return a URL for reading the resource, or <code>null</code> if
  573.      *         the resource could not be found
  574.      * @since  JDK1.1
  575.      */
  576.     public static URL getSystemResource(String name) {
  577.     try {
  578.         AccessController.beginPrivileged();
  579.         URLClassPath ucp = getSystemClassPath();
  580.         Resource res = ucp.getResource(name);
  581.         return res != null ? res.getURL() : null;
  582.     } finally {
  583.         AccessController.endPrivileged();
  584.     }
  585.     }
  586.  
  587.     /**
  588.      * Returns an enumeration of URLs specifying all of the system
  589.      * resources with the specified name. System resources are those
  590.      * loaded from the system class path.
  591.      *
  592.      * @param  name the resource name
  593.      * @return an enumeration of resource URLs
  594.      * @since  JDK1.2
  595.      */
  596.     public static Enumeration getSystemResources(String name) {
  597.     try {
  598.         AccessController.beginPrivileged();
  599.         final Enumeration e = getSystemClassPath().getResources(name);
  600.         return new Enumeration () {
  601.         public Object nextElement() {
  602.             return ((Resource)e.nextElement()).getURL();
  603.         }
  604.         public boolean hasMoreElements() {
  605.             return e.hasMoreElements();
  606.         }
  607.         };
  608.     } finally {
  609.         AccessController.endPrivileged();
  610.     }
  611.     }
  612.  
  613.     /*
  614.      * Returns the URLClassPath that is used for finding system resources.
  615.      */
  616.     static URLClassPath getSystemClassPath() {
  617.     if (systemClassPath == null) {
  618.         URL[] urls;
  619.         String prop = System.getProperty("java.sys.class.path");
  620.         if (prop == null) {
  621.         // We are running with the old-style launcher, so use
  622.         // java.class.path instead.
  623.         prop = System.getProperty("java.class.path");
  624.         }
  625.         if (prop != null) {
  626.         urls = java.net.URLClassLoader.pathToURLs(prop);
  627.         } else {
  628.         urls = new URL[0];
  629.         }
  630.         systemClassPath = new URLClassPath(urls);
  631.     }
  632.     return systemClassPath;
  633.     }
  634.  
  635.     private static URLClassPath systemClassPath;
  636.  
  637.     /**
  638.      * Returns an input stream for reading the specified resource.
  639.      * 
  640.      * @param  name the resource name
  641.      * @return an input stream for reading the resource, or <code>null</code>
  642.      *         if the resource could not be found
  643.      * @since  JDK1.1
  644.      */
  645.     public InputStream getResourceAsStream(String name) {
  646.     URL url = getResource(name);
  647.     try {
  648.         return url != null ? url.openStream() : null;
  649.     } catch (IOException e) {
  650.         return null;
  651.     }
  652.     }
  653.  
  654.     /**
  655.      * Returns an input stream for reading the specified system resource.
  656.      * System resources are those loaded from the system class path.
  657.      *
  658.      * @param  name the resource name
  659.      * @return an input stream for reading the resource, or <code>null</code>
  660.      *         if the resource could not be found
  661.      * @since  JDK1.1
  662.      */
  663.     public static InputStream getSystemResourceAsStream(String name) {
  664.     URL url = getSystemResource(name);
  665.     try {
  666.         return url != null ? url.openStream() : null;
  667.     } catch (IOException e) {
  668.         return null;
  669.     }
  670.     }
  671.  
  672.     /**
  673.      * Returns the base class loader for delegation. This is the default
  674.      * delegation parent for new <code>ClassLoader</code> instances, and
  675.      * is usually the <code>ClassLoader</code> that was used to start the
  676.      * application.
  677.      *
  678.      * @return the base <code>ClassLoader</code> for delegation, or
  679.      *         <code>null</code> if none
  680.      * @exception SecurityException if the caller does not have
  681.      *            <code>RuntimePermission("getClassLoader")</code> permission
  682.      * @since JDK1.2
  683.      */
  684.     public static ClassLoader getBaseClassLoader() {
  685.     SecurityManager sm = System.getSecurityManager();
  686.     if (sm != null) {
  687.         sm.checkPermission(getClassLoaderPerm);
  688.     }
  689.     if (!baseSet) {
  690.         Launcher l = Launcher.getLauncher();
  691.         if (l != null) {
  692.         base = l.getClassLoader();
  693.         }
  694.         baseSet = true;
  695.     }
  696.     return base;
  697.     }
  698.  
  699.     private static ClassLoader base;
  700.     private static boolean baseSet;
  701.  
  702.     private static final RuntimePermission getClassLoaderPerm =
  703.     new RuntimePermission("getClassLoader");
  704.  
  705.     /**
  706.      * Defines a package by name in this ClassLoader. This allows class
  707.      * loaders to define the packages for their classes. Packages must be
  708.      * created before the class is defined, and package names must be
  709.      * unique within a class loader and cannot be redefined or changed
  710.      * once created.
  711.      *
  712.      * @param name        the package name
  713.      * @param specTitle   the specification title
  714.      * @param specVersion the specification version
  715.      * @param specVendor  the specification vendor
  716.      * @param implTitle   the implementation title
  717.      * @param implVersion the implementation version
  718.      * @param implVendor  the implementation vendor
  719.      * @param sealBase    if specified, then this package is sealed with
  720.      *                    respect to the given base URL
  721.      * @exception IllegalArgumentException
  722.      *            if package name duplicates and existing package either in
  723.      *            this class loader or the parent class loader
  724.      */
  725.     protected Package definePackage(String name, String specTitle,
  726.                     String specVersion, String specVendor,
  727.                     String implTitle, String implVersion,
  728.                     String implVendor, URL sealBase)
  729.     throws IllegalArgumentException
  730.     {
  731.     Package pkg = getPackage(name);
  732.     if (pkg != null) {
  733.         throw new IllegalArgumentException(name);
  734.     }
  735.     pkg = new Package(name, specTitle, specVersion, specVendor,
  736.                 implTitle, implVersion, implVendor,
  737.                 sealBase);
  738.     packages.put(name, pkg);
  739.     return pkg;
  740.     }
  741.  
  742.     /**
  743.      * Returns the Package defined in this ClassLoader for the given name.
  744.      *
  745.      * @param name the package name
  746.      * @return the Package corresponding to the given name, or null if not
  747.      *         found
  748.      */
  749.     protected Package getPackage(String name) {
  750.     Package pkg = (Package)packages.get(name);
  751.     if (pkg != null) {
  752.         return pkg;
  753.     } else if (parent != null) {
  754.         return parent.getPackage(name);
  755.     } else {
  756.         return Package.getSystemPackage(name);
  757.     }
  758.     }
  759.  
  760.     /**
  761.      * Returns all of the Packages defined in this ClassLoader.
  762.      */
  763.     protected Package[] getPackages() {
  764.     Hashtable ptab = (Hashtable)packages.clone();
  765.     Package[] pkgs;
  766.     if (parent != null) {
  767.         pkgs = parent.getPackages();
  768.     } else {
  769.         pkgs = Package.getSystemPackages();
  770.     }
  771.     if (pkgs != null) {
  772.         for (int i = 0; i < pkgs.length; i++) {
  773.         ptab.put(pkgs[i].getName(), pkgs[i]);
  774.         }
  775.     }
  776.     Enumeration e = ptab.elements();
  777.     pkgs = new Package[ptab.size()];
  778.     for (int i = 0; i < pkgs.length; i++) {
  779.         pkgs[i] = (Package)e.nextElement();
  780.     }
  781.     return pkgs;
  782.     }
  783.  
  784.     /**
  785.      * The inner class NativeLibrary denotes a loaded native library 
  786.      * instance. Every classloader contains a vector of loaded native
  787.      * libraries in the private field <code>nativeLibraries</code>.
  788.      * The native libraries loaded into the system are entered into
  789.      * the <code>systemNativeLibraries</code> vector.
  790.      *
  791.      * Every native library reuqires a particular version of JNI. This
  792.      * is denoted by the private jniVersion field. This field is set
  793.      * by the VM when it loads the library, and used by the VM to pass
  794.      * the correct version of JNI to the native methods.
  795.      *
  796.      * @version 1.91, 03/18/98
  797.      * @see     java.lang.ClassLoader
  798.      * @since   JDK1.2
  799.      */ 
  800.     static class NativeLibrary {
  801.         /* opaque handle to native library, used in native code. */ 
  802.         long handle;
  803.         /* the version of JNI environment the native library requires. */
  804.         private int jniVersion;
  805.         /* the loader this native library belongs. */
  806.         private ClassLoader loader;
  807.         /* the canonicalized name of the native library. */
  808.         String name;
  809.         /* a list of objects the native library keeps reference to. */
  810.         private Vector objects;
  811.  
  812.         native void load(String name);
  813.         native long find(String name);
  814.         native void unload();
  815.  
  816.         public NativeLibrary(ClassLoader loader, String name) {
  817.             this.name = name;
  818.         this.loader = loader;
  819.         objects = new Vector();
  820.     }
  821.  
  822.         protected void finalize() {
  823.         synchronized (loadedLibraryNames) {
  824.             if (handle != 0) {
  825.             /* remove the native library name */ 
  826.             int size = loadedLibraryNames.size();
  827.             for (int i = 0; i < size; i++) {
  828.                 if (name.equals(loadedLibraryNames.elementAt(i))) {
  829.                 loadedLibraryNames.removeElementAt(i);
  830.                 break;
  831.             }
  832.             }
  833.             /* unload the library. */
  834.             unload();
  835.         }   
  836.         }
  837.     }
  838.  
  839.         /**
  840.      * This method registers an object with the native library, so that
  841.      * the object does not get collected until the native library can be
  842.      * unloaded. 
  843.      *
  844.      * This is usually called in the native methods, where the
  845.      * field and method IDs are computed and cached. By registering the
  846.      * class objcts with the native library, the field and method IDs
  847.      * remain valid until the native library is unloaded.
  848.      *
  849.      * @param obj  the objected to be registered with the native library.
  850.      * @since JDK1.2
  851.      */
  852.     public void registerObject(Object obj) {
  853.         objects.addElement(obj);
  854.     }
  855.     }
  856.  
  857.     /* the "default" domain. Set as the default ProtectionDomain
  858.      * on newly created classses.
  859.      */
  860.     private ProtectionDomain defaultDomain = null;
  861.  
  862.     /*
  863.      * returns (and initializes) the default domain.
  864.      */
  865.  
  866.     private ProtectionDomain getDefaultDomain() {
  867.     if (defaultDomain == null) {
  868.         synchronized(ClassLoader.class) {
  869.         if (defaultDomain == null) {
  870.             CodeSource cs = new CodeSource(null, null);
  871.             try {
  872.             java.security.AccessController.beginPrivileged();
  873.                 defaultDomain = new ProtectionDomain(cs,
  874.                       Policy.getPolicy().evaluate(cs));
  875.             } finally {
  876.             java.security.AccessController.endPrivileged();
  877.             }
  878.         }
  879.         }
  880.     }
  881.     return defaultDomain;
  882.     }
  883.  
  884.     /* All native library names we've loaded. */ 
  885.     private static Vector loadedLibraryNames = new Vector();
  886.     /* Native libraries belonging to system classes. */
  887.     private static Vector systemNativeLibraries = new Vector();
  888.     /* Native libraries associated with the class loader. */
  889.     private Vector nativeLibraries = new Vector();
  890.  
  891.     /* native libraries being loaded. */
  892.     private static Stack librariesBeingLoaded = new Stack();
  893.  
  894.     /* Called in the java.lang.Runtime class to implement load
  895.      * and loadLibrary.
  896.      *
  897.      * returns true on success, false on failure.
  898.      */
  899.     static boolean loadLibrary(ClassLoader loader, String name) {
  900.         Vector libs = 
  901.         loader != null ? loader.nativeLibraries : systemNativeLibraries;
  902.     synchronized (libs) {
  903.         int size = libs.size();
  904.         for (int i = 0; i < size; i++) {
  905.             NativeLibrary lib = (NativeLibrary)libs.elementAt(i);
  906.         if (name.equals(lib.name)) {
  907.             return true;
  908.         }
  909.         }        
  910.  
  911.         synchronized (loadedLibraryNames) {
  912.             if (loadedLibraryNames.contains(name)) {
  913.             throw new UnsatisfiedLinkError 
  914.                 ("Native Library " + 
  915.              name + 
  916.              " already loaded in another classloader");
  917.         }
  918.         /* If the library is being loaded (must be by
  919.          * the same thread, because Runtime.load and 
  920.          * Runtime.loadLibrary are synchronous). The
  921.          * reason is can occur is that the JNI_OnLoad
  922.          * function can cause another loadLibrary call.
  923.          *
  924.          * Thus we can use a static stack to hold the list
  925.          * of libraries we are loading.
  926.          *
  927.          * If there is a pending load operation for the
  928.          * library, we immediately return success; otherwise,
  929.          * we raise UnsatisfiedLinkError.
  930.          */
  931.         int n = librariesBeingLoaded.size();
  932.         for (int i = 0; i < n; i++) {
  933.             NativeLibrary lib = (NativeLibrary)
  934.                 librariesBeingLoaded.elementAt(i);
  935.             if (name.equals(lib.name)) {
  936.                 if (loader == lib.loader) {
  937.                 return true;
  938.             } else {
  939.                 throw new UnsatisfiedLinkError 
  940.                     ("Native Library " + 
  941.                  name + 
  942.                  " is being loaded in another classloader");
  943.             }
  944.             }
  945.         }
  946.         NativeLibrary lib = new NativeLibrary(loader, name);
  947.         librariesBeingLoaded.push(lib);
  948.         try {
  949.             lib.load(name);
  950.             if (lib.handle != 0) {
  951.                 loadedLibraryNames.addElement(name);
  952.             libs.addElement(lib);
  953.             return true;
  954.             } else {
  955.                 return false;
  956.             }
  957.         } finally {
  958.             librariesBeingLoaded.pop();
  959.         }
  960.         }
  961.     }
  962.     }
  963.  
  964.     /* Called in the VM class linking code. */
  965.     static long findNative(ClassLoader loader, String name) {
  966.         Vector libs = 
  967.         loader != null ? loader.nativeLibraries : systemNativeLibraries;
  968.     synchronized (libs) {
  969.         int size = libs.size();
  970.         for (int i = 0; i < size; i++) {
  971.             NativeLibrary lib = (NativeLibrary)libs.elementAt(i);
  972.         long entry = lib.find(name);
  973.         if (entry != 0)
  974.             return entry;
  975.         }
  976.     }
  977.     return 0;
  978.     }
  979. }
  980.