Source Code Cross Referenced for ClassLoader.java in  » 6.0-JDK-Core » lang » java » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » lang » java.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1994-2005 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025        package java.lang;
0026
0027        import java.io.InputStream;
0028        import java.io.IOException;
0029        import java.io.File;
0030        import java.lang.reflect.Constructor;
0031        import java.lang.reflect.InvocationTargetException;
0032        import java.net.MalformedURLException;
0033        import java.net.URL;
0034        import java.security.AccessController;
0035        import java.security.AccessControlContext;
0036        import java.security.CodeSource;
0037        import java.security.Policy;
0038        import java.security.PrivilegedAction;
0039        import java.security.PrivilegedActionException;
0040        import java.security.PrivilegedExceptionAction;
0041        import java.security.ProtectionDomain;
0042        import java.util.Enumeration;
0043        import java.util.Hashtable;
0044        import java.util.HashMap;
0045        import java.util.HashSet;
0046        import java.util.Set;
0047        import java.util.Stack;
0048        import java.util.Map;
0049        import java.util.Vector;
0050        import sun.misc.ClassFileTransformer;
0051        import sun.misc.CompoundEnumeration;
0052        import sun.misc.Resource;
0053        import sun.misc.URLClassPath;
0054        import sun.misc.VM;
0055        import sun.reflect.Reflection;
0056        import sun.security.util.SecurityConstants;
0057
0058        /**
0059         * A class loader is an object that is responsible for loading classes. The
0060         * class <tt>ClassLoader</tt> is an abstract class.  Given the <a
0061         * href="#name">binary name</a> of a class, a class loader should attempt to
0062         * locate or generate data that constitutes a definition for the class.  A
0063         * typical strategy is to transform the name into a file name and then read a
0064         * "class file" of that name from a file system.
0065         *
0066         * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
0067         * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
0068         * it.
0069         *
0070         * <p> <tt>Class</tt> objects for array classes are not created by class
0071         * loaders, but are created automatically as required by the Java runtime.
0072         * The class loader for an array class, as returned by {@link
0073         * Class#getClassLoader()} is the same as the class loader for its element
0074         * type; if the element type is a primitive type, then the array class has no
0075         * class loader.
0076         *
0077         * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
0078         * extend the manner in which the Java virtual machine dynamically loads
0079         * classes.
0080         *
0081         * <p> Class loaders may typically be used by security managers to indicate
0082         * security domains.
0083         *
0084         * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
0085         * classes and resources.  Each instance of <tt>ClassLoader</tt> has an
0086         * associated parent class loader.  When requested to find a class or
0087         * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
0088         * class or resource to its parent class loader before attempting to find the
0089         * class or resource itself.  The virtual machine's built-in class loader,
0090         * called the "bootstrap class loader", does not itself have a parent but may
0091         * serve as the parent of a <tt>ClassLoader</tt> instance.
0092         *
0093         * <p> Normally, the Java virtual machine loads classes from the local file
0094         * system in a platform-dependent manner.  For example, on UNIX systems, the
0095         * virtual machine loads classes from the directory defined by the
0096         * <tt>CLASSPATH</tt> environment variable.
0097         *
0098         * <p> However, some classes may not originate from a file; they may originate
0099         * from other sources, such as the network, or they could be constructed by an
0100         * application.  The method {@link #defineClass(String, byte[], int, int)
0101         * <tt>defineClass</tt>} converts an array of bytes into an instance of class
0102         * <tt>Class</tt>. Instances of this newly defined class can be created using
0103         * {@link Class#newInstance <tt>Class.newInstance</tt>}.
0104         *
0105         * <p> The methods and constructors of objects created by a class loader may
0106         * reference other classes.  To determine the class(es) referred to, the Java
0107         * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
0108         * the class loader that originally created the class.
0109         *
0110         * <p> For example, an application could create a network class loader to
0111         * download class files from a server.  Sample code might look like:
0112         *
0113         * <blockquote><pre>
0114         *   ClassLoader loader&nbsp;= new NetworkClassLoader(host,&nbsp;port);
0115         *   Object main&nbsp;= loader.loadClass("Main", true).newInstance();
0116         *	 &nbsp;.&nbsp;.&nbsp;.
0117         * </pre></blockquote>
0118         *
0119         * <p> The network class loader subclass must define the methods {@link
0120         * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
0121         * from the network.  Once it has downloaded the bytes that make up the class,
0122         * it should use the method {@link #defineClass <tt>defineClass</tt>} to
0123         * create a class instance.  A sample implementation is:
0124         *
0125         * <blockquote><pre>
0126         *     class NetworkClassLoader extends ClassLoader {
0127         *         String host;
0128         *         int port;
0129         *
0130         *         public Class findClass(String name) {
0131         *             byte[] b = loadClassData(name);
0132         *             return defineClass(name, b, 0, b.length);
0133         *         }
0134         *
0135         *         private byte[] loadClassData(String name) {
0136         *             // load the class data from the connection
0137         *             &nbsp;.&nbsp;.&nbsp;.
0138         *         }
0139         *     }
0140         * </pre></blockquote>
0141         *
0142         * <h4> <a name="name">Binary names</a> </h4>
0143         *
0144         * <p> Any class name provided as a {@link String} parameter to methods in
0145         * <tt>ClassLoader</tt> must be a binary name as defined by the <a
0146         * href="http://java.sun.com/docs/books/jls/">Java Language Specification</a>.
0147         *
0148         * <p> Examples of valid class names include:
0149         * <blockquote><pre>
0150         *   "java.lang.String"
0151         *   "javax.swing.JSpinner$DefaultEditor"
0152         *   "java.security.KeyStore$Builder$FileBuilder$1"
0153         *   "java.net.URLClassLoader$3$1"
0154         * </pre></blockquote>
0155         *
0156         * @version  1.195, 05/05/07
0157         * @see      #resolveClass(Class)
0158         * @since 1.0
0159         */
0160        public abstract class ClassLoader {
0161
0162            private static native void registerNatives();
0163
0164            static {
0165                registerNatives();
0166            }
0167
0168            // If initialization succeed this is set to true and security checks will
0169            // succeed.  Otherwise the object is not initialized and the object is
0170            // useless.
0171            private boolean initialized = false;
0172
0173            // The parent class loader for delegation
0174            private ClassLoader parent;
0175
0176            // Hashtable that maps packages to certs
0177            private Hashtable package2certs = new Hashtable(11);
0178
0179            // Shared among all packages with unsigned classes
0180            java.security.cert.Certificate[] nocerts;
0181
0182            // The classes loaded by this class loader.  The only purpose of this table
0183            // is to keep the classes from being GC'ed until the loader is GC'ed.
0184            private Vector classes = new Vector();
0185
0186            // The initiating protection domains for all classes loaded by this loader
0187            private Set domains = new HashSet();
0188
0189            // Invoked by the VM to record every loaded class with this loader.
0190            void addClass(Class c) {
0191                classes.addElement(c);
0192            }
0193
0194            // The packages defined in this class loader.  Each package name is mapped
0195            // to its corresponding Package object.
0196            private HashMap packages = new HashMap();
0197
0198            /**
0199             * Creates a new class loader using the specified parent class loader for
0200             * delegation.
0201             *
0202             * <p> If there is a security manager, its {@link
0203             * SecurityManager#checkCreateClassLoader()
0204             * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
0205             * a security exception.  </p>
0206             *
0207             * @param  parent
0208             *         The parent class loader
0209             *
0210             * @throws  SecurityException
0211             *          If a security manager exists and its
0212             *          <tt>checkCreateClassLoader</tt> method doesn't allow creation
0213             *          of a new class loader.
0214             *
0215             * @since  1.2
0216             */
0217            protected ClassLoader(ClassLoader parent) {
0218                SecurityManager security = System.getSecurityManager();
0219                if (security != null) {
0220                    security.checkCreateClassLoader();
0221                }
0222                this .parent = parent;
0223                initialized = true;
0224            }
0225
0226            /**
0227             * Creates a new class loader using the <tt>ClassLoader</tt> returned by
0228             * the method {@link #getSystemClassLoader()
0229             * <tt>getSystemClassLoader()</tt>} as the parent class loader.
0230             *
0231             * <p> If there is a security manager, its {@link
0232             * SecurityManager#checkCreateClassLoader()
0233             * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
0234             * a security exception.  </p>
0235             *
0236             * @throws  SecurityException
0237             *          If a security manager exists and its
0238             *          <tt>checkCreateClassLoader</tt> method doesn't allow creation
0239             *          of a new class loader.
0240             */
0241            protected ClassLoader() {
0242                SecurityManager security = System.getSecurityManager();
0243                if (security != null) {
0244                    security.checkCreateClassLoader();
0245                }
0246                this .parent = getSystemClassLoader();
0247                initialized = true;
0248            }
0249
0250            // -- Class --
0251
0252            /**
0253             * Loads the class with the specified <a href="#name">binary name</a>.
0254             * This method searches for classes in the same manner as the {@link
0255             * #loadClass(String, boolean)} method.  It is invoked by the Java virtual
0256             * machine to resolve class references.  Invoking this method is equivalent
0257             * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
0258             * false)</tt>}.  </p>
0259             *
0260             * @param  name
0261             *         The <a href="#name">binary name</a> of the class
0262             *
0263             * @return  The resulting <tt>Class</tt> object
0264             *
0265             * @throws  ClassNotFoundException
0266             *          If the class was not found
0267             */
0268            public Class<?> loadClass(String name)
0269                    throws ClassNotFoundException {
0270                return loadClass(name, false);
0271            }
0272
0273            /**
0274             * Loads the class with the specified <a href="#name">binary name</a>.  The
0275             * default implementation of this method searches for classes in the
0276             * following order:
0277             *
0278             * <p><ol>
0279             *
0280             *   <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
0281             *   has already been loaded.  </p></li>
0282             *
0283             *   <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
0284             *   on the parent class loader.  If the parent is <tt>null</tt> the class
0285             *   loader built-in to the virtual machine is used, instead.  </p></li>
0286             *
0287             *   <li><p> Invoke the {@link #findClass(String)} method to find the
0288             *   class.  </p></li>
0289             *
0290             * </ol>
0291             *
0292             * <p> If the class was found using the above steps, and the
0293             * <tt>resolve</tt> flag is true, this method will then invoke the {@link
0294             * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
0295             *
0296             * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
0297             * #findClass(String)}, rather than this method.  </p>
0298             *
0299             * @param  name
0300             *         The <a href="#name">binary name</a> of the class
0301             *
0302             * @param  resolve
0303             *         If <tt>true</tt> then resolve the class
0304             *
0305             * @return  The resulting <tt>Class</tt> object
0306             *
0307             * @throws  ClassNotFoundException
0308             *          If the class could not be found
0309             */
0310            protected synchronized Class<?> loadClass(String name,
0311                    boolean resolve) throws ClassNotFoundException {
0312                // First, check if the class has already been loaded
0313                Class c = findLoadedClass(name);
0314                if (c == null) {
0315                    try {
0316                        if (parent != null) {
0317                            c = parent.loadClass(name, false);
0318                        } else {
0319                            c = findBootstrapClass0(name);
0320                        }
0321                    } catch (ClassNotFoundException e) {
0322                        // If still not found, then invoke findClass in order
0323                        // to find the class.
0324                        c = findClass(name);
0325                    }
0326                }
0327                if (resolve) {
0328                    resolveClass(c);
0329                }
0330                return c;
0331            }
0332
0333            // This method is invoked by the virtual machine to load a class.
0334            private synchronized Class loadClassInternal(String name)
0335                    throws ClassNotFoundException {
0336                return loadClass(name);
0337            }
0338
0339            private void checkPackageAccess(Class cls, ProtectionDomain pd) {
0340                final SecurityManager sm = System.getSecurityManager();
0341                if (sm != null) {
0342                    final String name = cls.getName();
0343                    final int i = name.lastIndexOf('.');
0344                    if (i != -1) {
0345                        AccessController.doPrivileged(new PrivilegedAction() {
0346                            public Object run() {
0347                                sm.checkPackageAccess(name.substring(0, i));
0348                                return null;
0349                            }
0350                        }, new AccessControlContext(
0351                                new ProtectionDomain[] { pd }));
0352                    }
0353                }
0354                domains.add(pd);
0355            }
0356
0357            /**
0358             * Finds the class with the specified <a href="#name">binary name</a>.
0359             * This method should be overridden by class loader implementations that
0360             * follow the delegation model for loading classes, and will be invoked by
0361             * the {@link #loadClass <tt>loadClass</tt>} method after checking the
0362             * parent class loader for the requested class.  The default implementation
0363             * throws a <tt>ClassNotFoundException</tt>.  </p>
0364             *
0365             * @param  name
0366             *         The <a href="#name">binary name</a> of the class
0367             *
0368             * @return  The resulting <tt>Class</tt> object
0369             *
0370             * @throws  ClassNotFoundException
0371             *          If the class could not be found
0372             *
0373             * @since  1.2
0374             */
0375            protected Class<?> findClass(String name)
0376                    throws ClassNotFoundException {
0377                throw new ClassNotFoundException(name);
0378            }
0379
0380            /**
0381             * Converts an array of bytes into an instance of class <tt>Class</tt>.
0382             * Before the <tt>Class</tt> can be used it must be resolved.  This method
0383             * is deprecated in favor of the version that takes a <a
0384             * href="#name">binary name</a> as its first argument, and is more secure.
0385             *
0386             * @param  b
0387             *         The bytes that make up the class data.  The bytes in positions
0388             *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
0389             *         of a valid class file as defined by the <a
0390             *         href="http://java.sun.com/docs/books/vmspec/">Java Virtual
0391             *         Machine Specification</a>.
0392             *
0393             * @param  off
0394             *         The start offset in <tt>b</tt> of the class data
0395             *
0396             * @param  len
0397             *         The length of the class data
0398             *
0399             * @return  The <tt>Class</tt> object that was created from the specified
0400             *          class data
0401             *
0402             * @throws  ClassFormatError
0403             *          If the data did not contain a valid class
0404             *
0405             * @throws  IndexOutOfBoundsException
0406             *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
0407             *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
0408             *
0409             * @see  #loadClass(String, boolean)
0410             * @see  #resolveClass(Class)
0411             *
0412             * @deprecated  Replaced by {@link #defineClass(String, byte[], int, int)
0413             * defineClass(String, byte[], int, int)}
0414             */
0415            @Deprecated
0416            protected final Class<?> defineClass(byte[] b, int off, int len)
0417                    throws ClassFormatError {
0418                return defineClass(null, b, off, len, null);
0419            }
0420
0421            /**
0422             * Converts an array of bytes into an instance of class <tt>Class</tt>.
0423             * Before the <tt>Class</tt> can be used it must be resolved.
0424             *
0425             * <p> This method assigns a default {@link java.security.ProtectionDomain
0426             * <tt>ProtectionDomain</tt>} to the newly defined class.  The
0427             * <tt>ProtectionDomain</tt> is effectively granted the same set of
0428             * permissions returned when {@link
0429             * java.security.Policy#getPermissions(java.security.CodeSource)
0430             * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>}
0431             * is invoked.  The default domain is created on the first invocation of
0432             * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>},
0433             * and re-used on subsequent invocations.
0434             *
0435             * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use
0436             * the {@link #defineClass(String, byte[], int, int,
0437             * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a
0438             * <tt>ProtectionDomain</tt> as one of its arguments.  </p>
0439             *
0440             * @param  name
0441             *         The expected <a href="#name">binary name</a> of the class, or
0442             *         <tt>null</tt> if not known
0443             *
0444             * @param  b
0445             *         The bytes that make up the class data.  The bytes in positions
0446             *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
0447             *         of a valid class file as defined by the <a
0448             *         href="http://java.sun.com/docs/books/vmspec/">Java Virtual
0449             *         Machine Specification</a>.
0450             *
0451             * @param  off
0452             *         The start offset in <tt>b</tt> of the class data
0453             *
0454             * @param  len
0455             *         The length of the class data
0456             *
0457             * @return  The <tt>Class</tt> object that was created from the specified
0458             *          class data.
0459             *
0460             * @throws  ClassFormatError
0461             *          If the data did not contain a valid class
0462             *
0463             * @throws  IndexOutOfBoundsException
0464             *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
0465             *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
0466             *
0467             * @throws  SecurityException
0468             *          If an attempt is made to add this class to a package that
0469             *          contains classes that were signed by a different set of
0470             *          certificates than this class (which is unsigned), or if
0471             *          <tt>name</tt> begins with "<tt>java.</tt>".
0472             *
0473             * @see  #loadClass(String, boolean)
0474             * @see  #resolveClass(Class)
0475             * @see  java.security.CodeSource
0476             * @see  java.security.SecureClassLoader
0477             *
0478             * @since  1.1
0479             */
0480            protected final Class<?> defineClass(String name, byte[] b,
0481                    int off, int len) throws ClassFormatError {
0482                return defineClass(name, b, off, len, null);
0483            }
0484
0485            /* Determine protection domain, and check that:
0486                - not define java.* class,
0487            - signer of this class matches signers for the rest of the classes in package.
0488             */
0489            private ProtectionDomain preDefineClass(String name,
0490                    ProtectionDomain protectionDomain) {
0491                if (!checkName(name))
0492                    throw new NoClassDefFoundError("IllegalName: " + name);
0493
0494                if ((name != null) && name.startsWith("java.")) {
0495                    throw new SecurityException("Prohibited package name: "
0496                            + name.substring(0, name.lastIndexOf('.')));
0497                }
0498                if (protectionDomain == null) {
0499                    protectionDomain = getDefaultDomain();
0500                }
0501
0502                if (name != null)
0503                    checkCerts(name, protectionDomain.getCodeSource());
0504
0505                return protectionDomain;
0506            }
0507
0508            private String defineClassSourceLocation(
0509                    ProtectionDomain protectionDomain) {
0510                CodeSource cs = protectionDomain.getCodeSource();
0511                String source = null;
0512                if (cs != null && cs.getLocation() != null) {
0513                    source = cs.getLocation().toString();
0514                }
0515                return source;
0516            }
0517
0518            private Class defineTransformedClass(String name, byte[] b,
0519                    int off, int len, ProtectionDomain protectionDomain,
0520                    ClassFormatError cfe, String source)
0521                    throws ClassFormatError {
0522                // Class format error - try to transform the bytecode and
0523                // define the class again
0524                //
0525                Object[] transformers = ClassFileTransformer.getTransformers();
0526                Class c = null;
0527
0528                for (int i = 0; transformers != null && i < transformers.length; i++) {
0529                    try {
0530                        // Transform byte code using transformer
0531                        byte[] tb = ((ClassFileTransformer) transformers[i])
0532                                .transform(b, off, len);
0533                        c = defineClass1(name, tb, 0, tb.length,
0534                                protectionDomain, source);
0535                        break;
0536                    } catch (ClassFormatError cfe2) {
0537                        // If ClassFormatError occurs, try next transformer
0538                    }
0539                }
0540
0541                // Rethrow original ClassFormatError if unable to transform
0542                // bytecode to well-formed
0543                //
0544                if (c == null)
0545                    throw cfe;
0546
0547                return c;
0548            }
0549
0550            private void postDefineClass(Class c,
0551                    ProtectionDomain protectionDomain) {
0552                if (protectionDomain.getCodeSource() != null) {
0553                    java.security.cert.Certificate certs[] = protectionDomain
0554                            .getCodeSource().getCertificates();
0555                    if (certs != null)
0556                        setSigners(c, certs);
0557                }
0558            }
0559
0560            /**
0561             * Converts an array of bytes into an instance of class <tt>Class</tt>,
0562             * with an optional <tt>ProtectionDomain</tt>.  If the domain is
0563             * <tt>null</tt>, then a default domain will be assigned to the class as
0564             * specified in the documentation for {@link #defineClass(String, byte[],
0565             * int, int)}.  Before the class can be used it must be resolved.
0566             *
0567             * <p> The first class defined in a package determines the exact set of
0568             * certificates that all subsequent classes defined in that package must
0569             * contain.  The set of certificates for a class is obtained from the
0570             * {@link java.security.CodeSource <tt>CodeSource</tt>} within the
0571             * <tt>ProtectionDomain</tt> of the class.  Any classes added to that
0572             * package must contain the same set of certificates or a
0573             * <tt>SecurityException</tt> will be thrown.  Note that if
0574             * <tt>name</tt> is <tt>null</tt>, this check is not performed.
0575             * You should always pass in the <a href="#name">binary name</a> of the
0576             * class you are defining as well as the bytes.  This ensures that the
0577             * class you are defining is indeed the class you think it is.
0578             *
0579             * <p> The specified <tt>name</tt> cannot begin with "<tt>java.</tt>", since
0580             * all classes in the "<tt>java.*</tt> packages can only be defined by the
0581             * bootstrap class loader.  If <tt>name</tt> is not <tt>null</tt>, it
0582             * must be equal to the <a href="#name">binary name</a> of the class
0583             * specified by the byte array "<tt>b</tt>", otherwise a {@link
0584             * <tt>NoClassDefFoundError</tt>} will be thrown.  </p>
0585             *
0586             * @param  name
0587             *         The expected <a href="#name">binary name</a> of the class, or
0588             *         <tt>null</tt> if not known
0589             *
0590             * @param  b
0591             *         The bytes that make up the class data. The bytes in positions
0592             *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
0593             *         of a valid class file as defined by the <a
0594             *         href="http://java.sun.com/docs/books/vmspec/">Java Virtual
0595             *         Machine Specification</a>.
0596             *
0597             * @param  off
0598             *         The start offset in <tt>b</tt> of the class data
0599             *
0600             * @param  len
0601             *         The length of the class data
0602             *
0603             * @param  protectionDomain
0604             *         The ProtectionDomain of the class
0605             *
0606             * @return  The <tt>Class</tt> object created from the data,
0607             *          and optional <tt>ProtectionDomain</tt>.
0608             *
0609             * @throws  ClassFormatError
0610             *          If the data did not contain a valid class
0611             *
0612             * @throws  NoClassDefFoundError
0613             *          If <tt>name</tt> is not equal to the <a href="#name">binary
0614             *          name</a> of the class specified by <tt>b</tt>
0615             *
0616             * @throws  IndexOutOfBoundsException
0617             *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
0618             *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
0619             *
0620             * @throws  SecurityException
0621             *          If an attempt is made to add this class to a package that
0622             *          contains classes that were signed by a different set of
0623             *          certificates than this class, or if <tt>name</tt> begins with
0624             *          "<tt>java.</tt>".
0625             */
0626            protected final Class<?> defineClass(String name, byte[] b,
0627                    int off, int len, ProtectionDomain protectionDomain)
0628                    throws ClassFormatError {
0629                check();
0630                protectionDomain = preDefineClass(name, protectionDomain);
0631
0632                Class c = null;
0633                String source = defineClassSourceLocation(protectionDomain);
0634
0635                try {
0636                    c = defineClass1(name, b, off, len, protectionDomain,
0637                            source);
0638                } catch (ClassFormatError cfe) {
0639                    c = defineTransformedClass(name, b, off, len,
0640                            protectionDomain, cfe, source);
0641                }
0642
0643                postDefineClass(c, protectionDomain);
0644                return c;
0645            }
0646
0647            /**
0648             * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>}
0649             * into an instance of class <tt>Class</tt>,
0650             * with an optional <tt>ProtectionDomain</tt>.  If the domain is
0651             * <tt>null</tt>, then a default domain will be assigned to the class as
0652             * specified in the documentation for {@link #defineClass(String, byte[],
0653             * int, int)}.  Before the class can be used it must be resolved.
0654             *
0655             * <p>The rules about the first class defined in a package determining the set of
0656             * certificates for the package, and the restrictions on class names are identical
0657             * to those specified in the documentation for {@link #defineClass(String, byte[],
0658             * int, int, ProtectionDomain)}.
0659             *
0660             * <p> An invocation of this method of the form
0661             * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>
0662             * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
0663             * result as the statements
0664             *
0665             * <blockquote><tt>
0666             * ...<br>
0667             * byte[] temp = new byte[</tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#remaining
0668             * remaining}()];<br>
0669             * 	   </tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#get(byte[])
0670             * get}(temp);<br>
0671             *     return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
0672             * </tt><i>cl</i><tt>.defineClass}(</tt><i>name</i><tt>, temp, 0, temp.length, </tt><i>pd</i><tt>);<br>
0673             * </tt></blockquote>
0674             *
0675             * @param  name
0676             *         The expected <a href="#name">binary name</a. of the class, or
0677             *         <tt>null</tt> if not known
0678             *
0679             * @param  b
0680             *         The bytes that make up the class data. The bytes from positions
0681             *         <tt>b.position()</tt> through <tt>b.position() + b.limit() -1 </tt>
0682             *         should have the format of a valid class file as defined by the <a
0683             *         href="http://java.sun.com/docs/books/vmspec/">Java Virtual
0684             *         Machine Specification</a>.
0685             *
0686             * @param  protectionDomain
0687             *         The ProtectionDomain of the class, or <tt>null</tt>.
0688             *
0689             * @return  The <tt>Class</tt> object created from the data,
0690             *          and optional <tt>ProtectionDomain</tt>.
0691             *
0692             * @throws  ClassFormatError
0693             *          If the data did not contain a valid class.
0694             *
0695             * @throws  NoClassDefFoundError
0696             *          If <tt>name</tt> is not equal to the <a href="#name">binary
0697             *          name</a> of the class specified by <tt>b</tt>
0698             *
0699             * @throws  SecurityException
0700             *          If an attempt is made to add this class to a package that
0701             *          contains classes that were signed by a different set of
0702             *          certificates than this class, or if <tt>name</tt> begins with
0703             *          "<tt>java.</tt>".
0704             *
0705             * @see      #defineClass(String, byte[], int, int, ProtectionDomain)
0706             *
0707             * @since  1.5
0708             */
0709            protected final Class<?> defineClass(String name,
0710                    java.nio.ByteBuffer b, ProtectionDomain protectionDomain)
0711                    throws ClassFormatError {
0712                check();
0713
0714                int len = b.remaining();
0715
0716                // Use byte[] if not a direct ByteBufer:
0717                if (!b.isDirect()) {
0718                    if (b.hasArray()) {
0719                        return defineClass(name, b.array(), b.position()
0720                                + b.arrayOffset(), len, protectionDomain);
0721                    } else {
0722                        // no array, or read-only array
0723                        byte[] tb = new byte[len];
0724                        b.get(tb); // get bytes out of byte buffer.
0725                        return defineClass(name, tb, 0, len, protectionDomain);
0726                    }
0727                }
0728
0729                protectionDomain = preDefineClass(name, protectionDomain);
0730
0731                Class c = null;
0732                String source = defineClassSourceLocation(protectionDomain);
0733
0734                try {
0735                    c = defineClass2(name, b, b.position(), len,
0736                            protectionDomain, source);
0737                } catch (ClassFormatError cfe) {
0738                    byte[] tb = new byte[len];
0739                    b.get(tb); // get bytes out of byte buffer.
0740                    c = defineTransformedClass(name, tb, 0, len,
0741                            protectionDomain, cfe, source);
0742                }
0743
0744                postDefineClass(c, protectionDomain);
0745                return c;
0746            }
0747
0748            private native Class defineClass0(String name, byte[] b, int off,
0749                    int len, ProtectionDomain pd);
0750
0751            private native Class defineClass1(String name, byte[] b, int off,
0752                    int len, ProtectionDomain pd, String source);
0753
0754            private native Class defineClass2(String name,
0755                    java.nio.ByteBuffer b, int off, int len,
0756                    ProtectionDomain pd, String source);
0757
0758            // true if the name is null or has the potential to be a valid binary name
0759            private boolean checkName(String name) {
0760                if ((name == null) || (name.length() == 0))
0761                    return true;
0762                if ((name.indexOf('/') != -1)
0763                        || (!VM.allowArraySyntax() && (name.charAt(0) == '[')))
0764                    return false;
0765                return true;
0766            }
0767
0768            private synchronized void checkCerts(String name, CodeSource cs) {
0769                int i = name.lastIndexOf('.');
0770                String pname = (i == -1) ? "" : name.substring(0, i);
0771                java.security.cert.Certificate[] pcerts = (java.security.cert.Certificate[]) package2certs
0772                        .get(pname);
0773                if (pcerts == null) {
0774                    // first class in this package gets to define which
0775                    // certificates must be the same for all other classes
0776                    // in this package
0777                    if (cs != null) {
0778                        pcerts = cs.getCertificates();
0779                    }
0780                    if (pcerts == null) {
0781                        if (nocerts == null)
0782                            nocerts = new java.security.cert.Certificate[0];
0783                        pcerts = nocerts;
0784                    }
0785                    package2certs.put(pname, pcerts);
0786                } else {
0787                    java.security.cert.Certificate[] certs = null;
0788                    if (cs != null) {
0789                        certs = cs.getCertificates();
0790                    }
0791
0792                    if (!compareCerts(pcerts, certs)) {
0793                        throw new SecurityException(
0794                                "class \""
0795                                        + name
0796                                        + "\"'s signer information does not match signer information of other classes in the same package");
0797                    }
0798                }
0799            }
0800
0801            /**
0802             * check to make sure the certs for the new class (certs) are the same as
0803             * the certs for the first class inserted in the package (pcerts)
0804             */
0805            private boolean compareCerts(
0806                    java.security.cert.Certificate[] pcerts,
0807                    java.security.cert.Certificate[] certs) {
0808                // certs can be null, indicating no certs.
0809                if ((certs == null) || (certs.length == 0)) {
0810                    return pcerts.length == 0;
0811                }
0812
0813                // the length must be the same at this point
0814                if (certs.length != pcerts.length)
0815                    return false;
0816
0817                // go through and make sure all the certs in one array
0818                // are in the other and vice-versa.
0819                boolean match;
0820                for (int i = 0; i < certs.length; i++) {
0821                    match = false;
0822                    for (int j = 0; j < pcerts.length; j++) {
0823                        if (certs[i].equals(pcerts[j])) {
0824                            match = true;
0825                            break;
0826                        }
0827                    }
0828                    if (!match)
0829                        return false;
0830                }
0831
0832                // now do the same for pcerts
0833                for (int i = 0; i < pcerts.length; i++) {
0834                    match = false;
0835                    for (int j = 0; j < certs.length; j++) {
0836                        if (pcerts[i].equals(certs[j])) {
0837                            match = true;
0838                            break;
0839                        }
0840                    }
0841                    if (!match)
0842                        return false;
0843                }
0844
0845                return true;
0846            }
0847
0848            /**
0849             * Links the specified class.  This (misleadingly named) method may be
0850             * used by a class loader to link a class.  If the class <tt>c</tt> has
0851             * already been linked, then this method simply returns. Otherwise, the
0852             * class is linked as described in the "Execution" chapter of the <a
0853             * href="http://java.sun.com/docs/books/jls/">Java Language
0854             * Specification</a>.
0855             * </p>
0856             *
0857             * @param  c
0858             *         The class to link
0859             *
0860             * @throws  NullPointerException
0861             *          If <tt>c</tt> is <tt>null</tt>.
0862             *
0863             * @see  #defineClass(String, byte[], int, int)
0864             */
0865            protected final void resolveClass(Class<?> c) {
0866                check();
0867                resolveClass0(c);
0868            }
0869
0870            private native void resolveClass0(Class c);
0871
0872            /**
0873             * Finds a class with the specified <a href="#name">binary name</a>,
0874             * loading it if necessary.
0875             *
0876             * <p> This method loads the class through the system class loader (see
0877             * {@link #getSystemClassLoader()}).  The <tt>Class</tt> object returned
0878             * might have more than one <tt>ClassLoader</tt> associated with it.
0879             * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,
0880             * because most class loaders need to override just {@link
0881             * #findClass(String)}.  </p>
0882             *
0883             * @param  name
0884             *         The <a href="#name">binary name</a> of the class
0885             *
0886             * @return  The <tt>Class</tt> object for the specified <tt>name</tt>
0887             *
0888             * @throws  ClassNotFoundException
0889             *          If the class could not be found
0890             *
0891             * @see  #ClassLoader(ClassLoader)
0892             * @see  #getParent()
0893             */
0894            protected final Class<?> findSystemClass(String name)
0895                    throws ClassNotFoundException {
0896                check();
0897                ClassLoader system = getSystemClassLoader();
0898                if (system == null) {
0899                    if (!checkName(name))
0900                        throw new ClassNotFoundException(name);
0901                    return findBootstrapClass(name);
0902                }
0903                return system.loadClass(name);
0904            }
0905
0906            private Class findBootstrapClass0(String name)
0907                    throws ClassNotFoundException {
0908                check();
0909                if (!checkName(name))
0910                    throw new ClassNotFoundException(name);
0911                return findBootstrapClass(name);
0912            }
0913
0914            private native Class findBootstrapClass(String name)
0915                    throws ClassNotFoundException;
0916
0917            // Check to make sure the class loader has been initialized.
0918            private void check() {
0919                if (!initialized) {
0920                    throw new SecurityException(
0921                            "ClassLoader object not initialized");
0922                }
0923            }
0924
0925            /**
0926             * Returns the class with the given <a href="#name">binary name</a> if this
0927             * loader has been recorded by the Java virtual machine as an initiating
0928             * loader of a class with that <a href="#name">binary name</a>.  Otherwise
0929             * <tt>null</tt> is returned.  </p>
0930             *
0931             * @param  name
0932             *         The <a href="#name">binary name</a> of the class
0933             *
0934             * @return  The <tt>Class</tt> object, or <tt>null</tt> if the class has
0935             *          not been loaded
0936             *
0937             * @since  1.1
0938             */
0939            protected final Class<?> findLoadedClass(String name) {
0940                check();
0941                if (!checkName(name))
0942                    return null;
0943                return findLoadedClass0(name);
0944            }
0945
0946            private native final Class findLoadedClass0(String name);
0947
0948            /**
0949             * Sets the signers of a class.  This should be invoked after defining a
0950             * class.  </p>
0951             *
0952             * @param  c
0953             *         The <tt>Class</tt> object
0954             *
0955             * @param  signers
0956             *         The signers for the class
0957             *
0958             * @since  1.1
0959             */
0960            protected final void setSigners(Class<?> c, Object[] signers) {
0961                check();
0962                c.setSigners(signers);
0963            }
0964
0965            // -- Resource --
0966
0967            /**
0968             * Finds the resource with the given name.  A resource is some data
0969             * (images, audio, text, etc) that can be accessed by class code in a way
0970             * that is independent of the location of the code.
0971             *
0972             * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
0973             * identifies the resource.
0974             *
0975             * <p> This method will first search the parent class loader for the
0976             * resource; if the parent is <tt>null</tt> the path of the class loader
0977             * built-in to the virtual machine is searched.  That failing, this method
0978             * will invoke {@link #findResource(String)} to find the resource.  </p>
0979             *
0980             * @param  name
0981             *         The resource name
0982             *
0983             * @return  A <tt>URL</tt> object for reading the resource, or
0984             *          <tt>null</tt> if the resource could not be found or the invoker
0985             *          doesn't have adequate  privileges to get the resource.
0986             *
0987             * @since  1.1
0988             */
0989            public URL getResource(String name) {
0990                URL url;
0991                if (parent != null) {
0992                    url = parent.getResource(name);
0993                } else {
0994                    url = getBootstrapResource(name);
0995                }
0996                if (url == null) {
0997                    url = findResource(name);
0998                }
0999                return url;
1000            }
1001
1002            /**
1003             * Finds all the resources with the given name. A resource is some data
1004             * (images, audio, text, etc) that can be accessed by class code in a way
1005             * that is independent of the location of the code.
1006             *
1007             * <p>The name of a resource is a <tt>/</tt>-separated path name that
1008             * identifies the resource.
1009             *
1010             * <p> The search order is described in the documentation for {@link
1011             * #getResource(String)}.  </p>
1012             *
1013             * @param  name
1014             *         The resource name
1015             *
1016             * @return  An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
1017             *          the resource.  If no resources could  be found, the enumeration
1018             *          will be empty.  Resources that the class loader doesn't have
1019             *          access to will not be in the enumeration.
1020             *
1021             * @throws  IOException
1022             *          If I/O errors occur
1023             *
1024             * @see  #findResources(String)
1025             *
1026             * @since  1.2
1027             */
1028            public Enumeration<URL> getResources(String name)
1029                    throws IOException {
1030                Enumeration[] tmp = new Enumeration[2];
1031                if (parent != null) {
1032                    tmp[0] = parent.getResources(name);
1033                } else {
1034                    tmp[0] = getBootstrapResources(name);
1035                }
1036                tmp[1] = findResources(name);
1037
1038                return new CompoundEnumeration(tmp);
1039            }
1040
1041            /**
1042             * Finds the resource with the given name. Class loader implementations
1043             * should override this method to specify where to find resources.  </p>
1044             *
1045             * @param  name
1046             *         The resource name
1047             *
1048             * @return  A <tt>URL</tt> object for reading the resource, or
1049             *          <tt>null</tt> if the resource could not be found
1050             *
1051             * @since  1.2
1052             */
1053            protected URL findResource(String name) {
1054                return null;
1055            }
1056
1057            /**
1058             * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
1059             * representing all the resources with the given name. Class loader
1060             * implementations should override this method to specify where to load
1061             * resources from.  </p>
1062             *
1063             * @param  name
1064             *         The resource name
1065             *
1066             * @return  An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
1067             *          the resources
1068             *
1069             * @throws  IOException
1070             *          If I/O errors occur
1071             *
1072             * @since  1.2
1073             */
1074            protected Enumeration<URL> findResources(String name)
1075                    throws IOException {
1076                return new CompoundEnumeration(new Enumeration[0]);
1077            }
1078
1079            /**
1080             * Find a resource of the specified name from the search path used to load
1081             * classes.  This method locates the resource through the system class
1082             * loader (see {@link #getSystemClassLoader()}).  </p>
1083             *
1084             * @param  name
1085             *         The resource name
1086             *
1087             * @return  A {@link java.net.URL <tt>URL</tt>} object for reading the
1088             *          resource, or <tt>null</tt> if the resource could not be found
1089             *
1090             * @since  1.1
1091             */
1092            public static URL getSystemResource(String name) {
1093                ClassLoader system = getSystemClassLoader();
1094                if (system == null) {
1095                    return getBootstrapResource(name);
1096                }
1097                return system.getResource(name);
1098            }
1099
1100            /**
1101             * Finds all resources of the specified name from the search path used to
1102             * load classes.  The resources thus found are returned as an
1103             * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
1104             * java.net.URL <tt>URL</tt>} objects.
1105             *
1106             * <p> The search order is described in the documentation for {@link
1107             * #getSystemResource(String)}.  </p>
1108             *
1109             * @param  name
1110             *         The resource name
1111             *
1112             * @return  An enumeration of resource {@link java.net.URL <tt>URL</tt>}
1113             *          objects
1114             *
1115             * @throws  IOException
1116             *          If I/O errors occur
1117
1118             * @since  1.2
1119             */
1120            public static Enumeration<URL> getSystemResources(String name)
1121                    throws IOException {
1122                ClassLoader system = getSystemClassLoader();
1123                if (system == null) {
1124                    return getBootstrapResources(name);
1125                }
1126                return system.getResources(name);
1127            }
1128
1129            /**
1130             * Find resources from the VM's built-in classloader.
1131             */
1132            private static URL getBootstrapResource(String name) {
1133                URLClassPath ucp = getBootstrapClassPath();
1134                Resource res = ucp.getResource(name);
1135                return res != null ? res.getURL() : null;
1136            }
1137
1138            /**
1139             * Find resources from the VM's built-in classloader.
1140             */
1141            private static Enumeration getBootstrapResources(String name)
1142                    throws IOException {
1143                final Enumeration e = getBootstrapClassPath()
1144                        .getResources(name);
1145                return new Enumeration() {
1146                    public Object nextElement() {
1147                        return ((Resource) e.nextElement()).getURL();
1148                    }
1149
1150                    public boolean hasMoreElements() {
1151                        return e.hasMoreElements();
1152                    }
1153                };
1154            }
1155
1156            // Returns the URLClassPath that is used for finding system resources.
1157            static URLClassPath getBootstrapClassPath() {
1158                if (bootstrapClassPath == null) {
1159                    bootstrapClassPath = sun.misc.Launcher
1160                            .getBootstrapClassPath();
1161                }
1162                return bootstrapClassPath;
1163            }
1164
1165            private static URLClassPath bootstrapClassPath;
1166
1167            /**
1168             * Returns an input stream for reading the specified resource.
1169             *
1170             * <p> The search order is described in the documentation for {@link
1171             * #getResource(String)}.  </p>
1172             *
1173             * @param  name
1174             *         The resource name
1175             *
1176             * @return  An input stream for reading the resource, or <tt>null</tt>
1177             *          if the resource could not be found
1178             *
1179             * @since  1.1
1180             */
1181            public InputStream getResourceAsStream(String name) {
1182                URL url = getResource(name);
1183                try {
1184                    return url != null ? url.openStream() : null;
1185                } catch (IOException e) {
1186                    return null;
1187                }
1188            }
1189
1190            /**
1191             * Open for reading, a resource of the specified name from the search path
1192             * used to load classes.  This method locates the resource through the
1193             * system class loader (see {@link #getSystemClassLoader()}).  </p>
1194             *
1195             * @param  name
1196             *         The resource name
1197             *
1198             * @return  An input stream for reading the resource, or <tt>null</tt>
1199             * 	        if the resource could not be found
1200             *
1201             * @since  1.1
1202             */
1203            public static InputStream getSystemResourceAsStream(String name) {
1204                URL url = getSystemResource(name);
1205                try {
1206                    return url != null ? url.openStream() : null;
1207                } catch (IOException e) {
1208                    return null;
1209                }
1210            }
1211
1212            // -- Hierarchy --
1213
1214            /**
1215             * Returns the parent class loader for delegation. Some implementations may
1216             * use <tt>null</tt> to represent the bootstrap class loader. This method
1217             * will return <tt>null</tt> in such implementations if this class loader's
1218             * parent is the bootstrap class loader.
1219             *
1220             * <p> If a security manager is present, and the invoker's class loader is
1221             * not <tt>null</tt> and is not an ancestor of this class loader, then this
1222             * method invokes the security manager's {@link
1223             * SecurityManager#checkPermission(java.security.Permission)
1224             * <tt>checkPermission</tt>} method with a {@link
1225             * RuntimePermission#RuntimePermission(String)
1226             * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
1227             * access to the parent class loader is permitted.  If not, a
1228             * <tt>SecurityException</tt> will be thrown.  </p>
1229             *
1230             * @return  The parent <tt>ClassLoader</tt>
1231             *
1232             * @throws  SecurityException
1233             *          If a security manager exists and its <tt>checkPermission</tt>
1234             *          method doesn't allow access to this class loader's parent class
1235             *          loader.
1236             *
1237             * @since  1.2
1238             */
1239            public final ClassLoader getParent() {
1240                if (parent == null)
1241                    return null;
1242                SecurityManager sm = System.getSecurityManager();
1243                if (sm != null) {
1244                    ClassLoader ccl = getCallerClassLoader();
1245                    if (ccl != null && !isAncestor(ccl)) {
1246                        sm
1247                                .checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
1248                    }
1249                }
1250                return parent;
1251            }
1252
1253            /**
1254             * Returns the system class loader for delegation.  This is the default
1255             * delegation parent for new <tt>ClassLoader</tt> instances, and is
1256             * typically the class loader used to start the application.
1257             *
1258             * <p> This method is first invoked early in the runtime's startup
1259             * sequence, at which point it creates the system class loader and sets it
1260             * as the context class loader of the invoking <tt>Thread</tt>.
1261             *
1262             * <p> The default system class loader is an implementation-dependent
1263             * instance of this class.
1264             *
1265             * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
1266             * when this method is first invoked then the value of that property is
1267             * taken to be the name of a class that will be returned as the system
1268             * class loader.  The class is loaded using the default system class loader
1269             * and must define a public constructor that takes a single parameter of
1270             * type <tt>ClassLoader</tt> which is used as the delegation parent.  An
1271             * instance is then created using this constructor with the default system
1272             * class loader as the parameter.  The resulting class loader is defined
1273             * to be the system class loader.
1274             *
1275             * <p> If a security manager is present, and the invoker's class loader is
1276             * not <tt>null</tt> and the invoker's class loader is not the same as or
1277             * an ancestor of the system class loader, then this method invokes the
1278             * security manager's {@link
1279             * SecurityManager#checkPermission(java.security.Permission)
1280             * <tt>checkPermission</tt>} method with a {@link
1281             * RuntimePermission#RuntimePermission(String)
1282             * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
1283             * access to the system class loader.  If not, a
1284             * <tt>SecurityException</tt> will be thrown.  </p>
1285             *
1286             * @return  The system <tt>ClassLoader</tt> for delegation, or
1287             *          <tt>null</tt> if none
1288             *
1289             * @throws  SecurityException
1290             *          If a security manager exists and its <tt>checkPermission</tt>
1291             *          method doesn't allow access to the system class loader.
1292             *
1293             * @throws  IllegalStateException
1294             *          If invoked recursively during the construction of the class
1295             *          loader specified by the "<tt>java.system.class.loader</tt>"
1296             *          property.
1297             *
1298             * @throws  Error
1299             *          If the system property "<tt>java.system.class.loader</tt>"
1300             *          is defined but the named class could not be loaded, the
1301             *          provider class does not define the required constructor, or an
1302             *          exception is thrown by that constructor when it is invoked. The
1303             *          underlying cause of the error can be retrieved via the
1304             *          {@link Throwable#getCause()} method.
1305             *
1306             * @revised  1.4
1307             */
1308            public static ClassLoader getSystemClassLoader() {
1309                initSystemClassLoader();
1310                if (scl == null) {
1311                    return null;
1312                }
1313                SecurityManager sm = System.getSecurityManager();
1314                if (sm != null) {
1315                    ClassLoader ccl = getCallerClassLoader();
1316                    if (ccl != null && ccl != scl && !scl.isAncestor(ccl)) {
1317                        sm
1318                                .checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
1319                    }
1320                }
1321                return scl;
1322            }
1323
1324            private static synchronized void initSystemClassLoader() {
1325                if (!sclSet) {
1326                    if (scl != null)
1327                        throw new IllegalStateException("recursive invocation");
1328                    sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
1329                    if (l != null) {
1330                        Throwable oops = null;
1331                        scl = l.getClassLoader();
1332                        try {
1333                            PrivilegedExceptionAction a;
1334                            a = new SystemClassLoaderAction(scl);
1335                            scl = (ClassLoader) AccessController
1336                                    .doPrivileged(a);
1337                        } catch (PrivilegedActionException pae) {
1338                            oops = pae.getCause();
1339                            if (oops instanceof  InvocationTargetException) {
1340                                oops = oops.getCause();
1341                            }
1342                        }
1343                        if (oops != null) {
1344                            if (oops instanceof  Error) {
1345                                throw (Error) oops;
1346                            } else {
1347                                // wrap the exception
1348                                throw new Error(oops);
1349                            }
1350                        }
1351                    }
1352                    sclSet = true;
1353                }
1354            }
1355
1356            // Returns true if the specified class loader can be found in this class
1357            // loader's delegation chain.
1358            boolean isAncestor(ClassLoader cl) {
1359                ClassLoader acl = this ;
1360                do {
1361                    acl = acl.parent;
1362                    if (cl == acl) {
1363                        return true;
1364                    }
1365                } while (acl != null);
1366                return false;
1367            }
1368
1369            // Returns the invoker's class loader, or null if none.
1370            // NOTE: This must always be invoked when there is exactly one intervening
1371            // frame from the core libraries on the stack between this method's
1372            // invocation and the desired invoker.
1373            static ClassLoader getCallerClassLoader() {
1374                // NOTE use of more generic Reflection.getCallerClass()
1375                Class caller = Reflection.getCallerClass(3);
1376                // This can be null if the VM is requesting it
1377                if (caller == null) {
1378                    return null;
1379                }
1380                // Circumvent security check since this is package-private
1381                return caller.getClassLoader0();
1382            }
1383
1384            // The class loader for the system
1385            private static ClassLoader scl;
1386
1387            // Set to true once the system class loader has been set
1388            private static boolean sclSet;
1389
1390            // -- Package --
1391
1392            /**
1393             * Defines a package by name in this <tt>ClassLoader</tt>.  This allows
1394             * class loaders to define the packages for their classes. Packages must
1395             * be created before the class is defined, and package names must be
1396             * unique within a class loader and cannot be redefined or changed once
1397             * created.  </p>
1398             *
1399             * @param  name
1400             *         The package name
1401             *
1402             * @param  specTitle
1403             *         The specification title
1404             *
1405             * @param  specVersion
1406             *         The specification version
1407             *
1408             * @param  specVendor
1409             *         The specification vendor
1410             *
1411             * @param  implTitle
1412             *         The implementation title
1413             *
1414             * @param  implVersion
1415             *         The implementation version
1416             *
1417             * @param  implVendor
1418             *         The implementation vendor
1419             *
1420             * @param  sealBase
1421             *         If not <tt>null</tt>, then this package is sealed with
1422             *         respect to the given code source {@link java.net.URL
1423             *         <tt>URL</tt>}  object.  Otherwise, the package is not sealed.
1424             *
1425             * @return  The newly defined <tt>Package</tt> object
1426             *
1427             * @throws  IllegalArgumentException
1428             *          If package name duplicates an existing package either in this
1429             *          class loader or one of its ancestors
1430             *
1431             * @since  1.2
1432             */
1433            protected Package definePackage(String name, String specTitle,
1434                    String specVersion, String specVendor, String implTitle,
1435                    String implVersion, String implVendor, URL sealBase)
1436                    throws IllegalArgumentException {
1437                synchronized (packages) {
1438                    Package pkg = getPackage(name);
1439                    if (pkg != null) {
1440                        throw new IllegalArgumentException(name);
1441                    }
1442                    pkg = new Package(name, specTitle, specVersion, specVendor,
1443                            implTitle, implVersion, implVendor, sealBase, this );
1444                    packages.put(name, pkg);
1445                    return pkg;
1446                }
1447            }
1448
1449            /**
1450             * Returns a <tt>Package</tt> that has been defined by this class loader
1451             * or any of its ancestors.  </p>
1452             *
1453             * @param  name
1454             *         The package name
1455             *
1456             * @return  The <tt>Package</tt> corresponding to the given name, or
1457             *          <tt>null</tt> if not found
1458             *
1459             * @since  1.2
1460             */
1461            protected Package getPackage(String name) {
1462                synchronized (packages) {
1463                    Package pkg = (Package) packages.get(name);
1464                    if (pkg == null) {
1465                        if (parent != null) {
1466                            pkg = parent.getPackage(name);
1467                        } else {
1468                            pkg = Package.getSystemPackage(name);
1469                        }
1470                        if (pkg != null) {
1471                            packages.put(name, pkg);
1472                        }
1473                    }
1474                    return pkg;
1475                }
1476            }
1477
1478            /**
1479             * Returns all of the <tt>Packages</tt> defined by this class loader and
1480             * its ancestors.  </p>
1481             *
1482             * @return  The array of <tt>Package</tt> objects defined by this
1483             *          <tt>ClassLoader</tt>
1484             *
1485             * @since  1.2
1486             */
1487            protected Package[] getPackages() {
1488                Map map;
1489                synchronized (packages) {
1490                    map = (Map) packages.clone();
1491                }
1492                Package[] pkgs;
1493                if (parent != null) {
1494                    pkgs = parent.getPackages();
1495                } else {
1496                    pkgs = Package.getSystemPackages();
1497                }
1498                if (pkgs != null) {
1499                    for (int i = 0; i < pkgs.length; i++) {
1500                        String pkgName = pkgs[i].getName();
1501                        if (map.get(pkgName) == null) {
1502                            map.put(pkgName, pkgs[i]);
1503                        }
1504                    }
1505                }
1506                return (Package[]) map.values()
1507                        .toArray(new Package[map.size()]);
1508            }
1509
1510            // -- Native library access --
1511
1512            /**
1513             * Returns the absolute path name of a native library.  The VM invokes this
1514             * method to locate the native libraries that belong to classes loaded with
1515             * this class loader. If this method returns <tt>null</tt>, the VM
1516             * searches the library along the path specified as the
1517             * "<tt>java.library.path</tt>" property.  </p>
1518             *
1519             * @param  libname
1520             *         The library name
1521             *
1522             * @return  The absolute path of the native library
1523             *
1524             * @see  System#loadLibrary(String)
1525             * @see  System#mapLibraryName(String)
1526             *
1527             * @since  1.2
1528             */
1529            protected String findLibrary(String libname) {
1530                return null;
1531            }
1532
1533            /**
1534             * The inner class NativeLibrary denotes a loaded native library instance.
1535             * Every classloader contains a vector of loaded native libraries in the
1536             * private field <tt>nativeLibraries</tt>.  The native libraries loaded
1537             * into the system are entered into the <tt>systemNativeLibraries</tt>
1538             * vector.
1539             *
1540             * <p> Every native library requires a particular version of JNI. This is
1541             * denoted by the private <tt>jniVersion</tt> field.  This field is set by
1542             * the VM when it loads the library, and used by the VM to pass the correct
1543             * version of JNI to the native methods.  </p>
1544             *
1545             * @version  1.195 05/05/07
1546             * @see      ClassLoader
1547             * @since    1.2
1548             */
1549            static class NativeLibrary {
1550                // opaque handle to native library, used in native code.
1551                long handle;
1552                // the version of JNI environment the native library requires.
1553                private int jniVersion;
1554                // the class from which the library is loaded, also indicates
1555                // the loader this native library belongs.
1556                private Class fromClass;
1557                // the canonicalized name of the native library.
1558                String name;
1559
1560                native void load(String name);
1561
1562                native long find(String name);
1563
1564                native void unload();
1565
1566                public NativeLibrary(Class fromClass, String name) {
1567                    this .name = name;
1568                    this .fromClass = fromClass;
1569                }
1570
1571                protected void finalize() {
1572                    synchronized (loadedLibraryNames) {
1573                        if (fromClass.getClassLoader() != null && handle != 0) {
1574                            /* remove the native library name */
1575                            int size = loadedLibraryNames.size();
1576                            for (int i = 0; i < size; i++) {
1577                                if (name
1578                                        .equals(loadedLibraryNames.elementAt(i))) {
1579                                    loadedLibraryNames.removeElementAt(i);
1580                                    break;
1581                                }
1582                            }
1583                            /* unload the library. */
1584                            ClassLoader.nativeLibraryContext.push(this );
1585                            try {
1586                                unload();
1587                            } finally {
1588                                ClassLoader.nativeLibraryContext.pop();
1589                            }
1590                        }
1591                    }
1592                }
1593
1594                // Invoked in the VM to determine the context class in
1595                // JNI_Load/JNI_Unload
1596                static Class getFromClass() {
1597                    return ((NativeLibrary) (ClassLoader.nativeLibraryContext
1598                            .peek())).fromClass;
1599                }
1600            }
1601
1602            // The "default" domain. Set as the default ProtectionDomain on newly
1603            // created classes.
1604            private ProtectionDomain defaultDomain = null;
1605
1606            // Returns (and initializes) the default domain.
1607            private synchronized ProtectionDomain getDefaultDomain() {
1608                if (defaultDomain == null) {
1609                    CodeSource cs = new CodeSource(null,
1610                            (java.security.cert.Certificate[]) null);
1611                    defaultDomain = new ProtectionDomain(cs, null, this , null);
1612                }
1613                return defaultDomain;
1614            }
1615
1616            // All native library names we've loaded.
1617            private static Vector loadedLibraryNames = new Vector();
1618            // Native libraries belonging to system classes.
1619            private static Vector systemNativeLibraries = new Vector();
1620            // Native libraries associated with the class loader.
1621            private Vector nativeLibraries = new Vector();
1622
1623            // native libraries being loaded/unloaded.
1624            private static Stack nativeLibraryContext = new Stack();
1625
1626            // The paths searched for libraries
1627            static private String usr_paths[];
1628            static private String sys_paths[];
1629
1630            private static String[] initializePath(String propname) {
1631                String ldpath = System.getProperty(propname, "");
1632                String ps = File.pathSeparator;
1633                int ldlen = ldpath.length();
1634                int i, j, n;
1635                // Count the separators in the path
1636                i = ldpath.indexOf(ps);
1637                n = 0;
1638                while (i >= 0) {
1639                    n++;
1640                    i = ldpath.indexOf(ps, i + 1);
1641                }
1642
1643                // allocate the array of paths - n :'s = n + 1 path elements
1644                String[] paths = new String[n + 1];
1645
1646                // Fill the array with paths from the ldpath
1647                n = i = 0;
1648                j = ldpath.indexOf(ps);
1649                while (j >= 0) {
1650                    if (j - i > 0) {
1651                        paths[n++] = ldpath.substring(i, j);
1652                    } else if (j - i == 0) {
1653                        paths[n++] = ".";
1654                    }
1655                    i = j + 1;
1656                    j = ldpath.indexOf(ps, i);
1657                }
1658                paths[n] = ldpath.substring(i, ldlen);
1659                return paths;
1660            }
1661
1662            // Invoked in the java.lang.Runtime class to implement load and loadLibrary.
1663            static void loadLibrary(Class fromClass, String name,
1664                    boolean isAbsolute) {
1665                ClassLoader loader = (fromClass == null) ? null : fromClass
1666                        .getClassLoader();
1667                if (sys_paths == null) {
1668                    usr_paths = initializePath("java.library.path");
1669                    sys_paths = initializePath("sun.boot.library.path");
1670                }
1671                if (isAbsolute) {
1672                    if (loadLibrary0(fromClass, new File(name))) {
1673                        return;
1674                    }
1675                    throw new UnsatisfiedLinkError("Can't load library: "
1676                            + name);
1677                }
1678                if (loader != null) {
1679                    String libfilename = loader.findLibrary(name);
1680                    if (libfilename != null) {
1681                        File libfile = new File(libfilename);
1682                        if (!libfile.isAbsolute()) {
1683                            throw new UnsatisfiedLinkError(
1684                                    "ClassLoader.findLibrary failed to return an absolute path: "
1685                                            + libfilename);
1686                        }
1687                        if (loadLibrary0(fromClass, libfile)) {
1688                            return;
1689                        }
1690                        throw new UnsatisfiedLinkError("Can't load "
1691                                + libfilename);
1692                    }
1693                }
1694                for (int i = 0; i < sys_paths.length; i++) {
1695                    File libfile = new File(sys_paths[i], System
1696                            .mapLibraryName(name));
1697                    if (loadLibrary0(fromClass, libfile)) {
1698                        return;
1699                    }
1700                }
1701                if (loader != null) {
1702                    for (int i = 0; i < usr_paths.length; i++) {
1703                        File libfile = new File(usr_paths[i], System
1704                                .mapLibraryName(name));
1705                        if (loadLibrary0(fromClass, libfile)) {
1706                            return;
1707                        }
1708                    }
1709                }
1710                // Oops, it failed
1711                throw new UnsatisfiedLinkError("no " + name
1712                        + " in java.library.path");
1713            }
1714
1715            private static boolean loadLibrary0(Class fromClass, final File file) {
1716                Boolean exists = (Boolean) AccessController
1717                        .doPrivileged(new PrivilegedAction() {
1718                            public Object run() {
1719                                return new Boolean(file.exists());
1720                            }
1721                        });
1722                if (!exists.booleanValue()) {
1723                    return false;
1724                }
1725                String name;
1726                try {
1727                    name = file.getCanonicalPath();
1728                } catch (IOException e) {
1729                    return false;
1730                }
1731                ClassLoader loader = (fromClass == null) ? null : fromClass
1732                        .getClassLoader();
1733                Vector libs = loader != null ? loader.nativeLibraries
1734                        : systemNativeLibraries;
1735                synchronized (libs) {
1736                    int size = libs.size();
1737                    for (int i = 0; i < size; i++) {
1738                        NativeLibrary lib = (NativeLibrary) libs.elementAt(i);
1739                        if (name.equals(lib.name)) {
1740                            return true;
1741                        }
1742                    }
1743
1744                    synchronized (loadedLibraryNames) {
1745                        if (loadedLibraryNames.contains(name)) {
1746                            throw new UnsatisfiedLinkError("Native Library "
1747                                    + name
1748                                    + " already loaded in another classloader");
1749                        }
1750                        /* If the library is being loaded (must be by the same thread,
1751                         * because Runtime.load and Runtime.loadLibrary are
1752                         * synchronous). The reason is can occur is that the JNI_OnLoad
1753                         * function can cause another loadLibrary invocation.
1754                         *
1755                         * Thus we can use a static stack to hold the list of libraries
1756                         * we are loading.
1757                         *
1758                         * If there is a pending load operation for the library, we
1759                         * immediately return success; otherwise, we raise
1760                         * UnsatisfiedLinkError.
1761                         */
1762                        int n = nativeLibraryContext.size();
1763                        for (int i = 0; i < n; i++) {
1764                            NativeLibrary lib = (NativeLibrary) nativeLibraryContext
1765                                    .elementAt(i);
1766                            if (name.equals(lib.name)) {
1767                                if (loader == lib.fromClass.getClassLoader()) {
1768                                    return true;
1769                                } else {
1770                                    throw new UnsatisfiedLinkError(
1771                                            "Native Library "
1772                                                    + name
1773                                                    + " is being loaded in another classloader");
1774                                }
1775                            }
1776                        }
1777                        NativeLibrary lib = new NativeLibrary(fromClass, name);
1778                        nativeLibraryContext.push(lib);
1779                        try {
1780                            lib.load(name);
1781                        } finally {
1782                            nativeLibraryContext.pop();
1783                        }
1784                        if (lib.handle != 0) {
1785                            loadedLibraryNames.addElement(name);
1786                            libs.addElement(lib);
1787                            return true;
1788                        }
1789                        return false;
1790                    }
1791                }
1792            }
1793
1794            // Invoked in the VM class linking code.
1795            static long findNative(ClassLoader loader, String name) {
1796                Vector libs = loader != null ? loader.nativeLibraries
1797                        : systemNativeLibraries;
1798                synchronized (libs) {
1799                    int size = libs.size();
1800                    for (int i = 0; i < size; i++) {
1801                        NativeLibrary lib = (NativeLibrary) libs.elementAt(i);
1802                        long entry = lib.find(name);
1803                        if (entry != 0)
1804                            return entry;
1805                    }
1806                }
1807                return 0;
1808            }
1809
1810            // -- Assertion management --
1811
1812            // The default toggle for assertion checking.
1813            private boolean defaultAssertionStatus = false;
1814
1815            // Maps String packageName to Boolean package default assertion status Note
1816            // that the default package is placed under a null map key.  If this field
1817            // is null then we are delegating assertion status queries to the VM, i.e.,
1818            // none of this ClassLoader's assertion status modification methods have
1819            // been invoked.
1820            private Map packageAssertionStatus = null;
1821
1822            // Maps String fullyQualifiedClassName to Boolean assertionStatus If this
1823            // field is null then we are delegating assertion status queries to the VM,
1824            // i.e., none of this ClassLoader's assertion status modification methods
1825            // have been invoked.
1826            Map classAssertionStatus = null;
1827
1828            /**
1829             * Sets the default assertion status for this class loader.  This setting
1830             * determines whether classes loaded by this class loader and initialized
1831             * in the future will have assertions enabled or disabled by default.
1832             * This setting may be overridden on a per-package or per-class basis by
1833             * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link
1834             * #setClassAssertionStatus(String, boolean)}.  </p>
1835             *
1836             * @param  enabled
1837             *         <tt>true</tt> if classes loaded by this class loader will
1838             *         henceforth have assertions enabled by default, <tt>false</tt>
1839             *         if they will have assertions disabled by default.
1840             *
1841             * @since  1.4
1842             */
1843            public synchronized void setDefaultAssertionStatus(boolean enabled) {
1844                if (classAssertionStatus == null)
1845                    initializeJavaAssertionMaps();
1846
1847                defaultAssertionStatus = enabled;
1848            }
1849
1850            /**
1851             * Sets the package default assertion status for the named package.  The
1852             * package default assertion status determines the assertion status for
1853             * classes initialized in the future that belong to the named package or
1854             * any of its "subpackages".
1855             *
1856             * <p> A subpackage of a package named p is any package whose name begins
1857             * with "<tt>p.</tt>".  For example, <tt>javax.swing.text</tt> is a
1858             * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and
1859             * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>.
1860             *
1861             * <p> In the event that multiple package defaults apply to a given class,
1862             * the package default pertaining to the most specific package takes
1863             * precedence over the others.  For example, if <tt>javax.lang</tt> and
1864             * <tt>javax.lang.reflect</tt> both have package defaults associated with
1865             * them, the latter package default applies to classes in
1866             * <tt>javax.lang.reflect</tt>.
1867             *
1868             * <p> Package defaults take precedence over the class loader's default
1869             * assertion status, and may be overridden on a per-class basis by invoking
1870             * {@link #setClassAssertionStatus(String, boolean)}.  </p>
1871             *
1872             * @param  packageName
1873             *         The name of the package whose package default assertion status
1874             *         is to be set. A <tt>null</tt> value indicates the unnamed
1875             *         package that is "current"
1876             *         (<a href="http://java.sun.com/docs/books/jls/">Java Language
1877             *         Specification</a>, section 7.4.2).
1878             *
1879             * @param  enabled
1880             *         <tt>true</tt> if classes loaded by this classloader and
1881             *         belonging to the named package or any of its subpackages will
1882             *         have assertions enabled by default, <tt>false</tt> if they will
1883             *         have assertions disabled by default.
1884             *
1885             * @since  1.4
1886             */
1887            public synchronized void setPackageAssertionStatus(
1888                    String packageName, boolean enabled) {
1889                if (packageAssertionStatus == null)
1890                    initializeJavaAssertionMaps();
1891
1892                packageAssertionStatus.put(packageName, Boolean
1893                        .valueOf(enabled));
1894            }
1895
1896            /**
1897             * Sets the desired assertion status for the named top-level class in this
1898             * class loader and any nested classes contained therein.  This setting
1899             * takes precedence over the class loader's default assertion status, and
1900             * over any applicable per-package default.  This method has no effect if
1901             * the named class has already been initialized.  (Once a class is
1902             * initialized, its assertion status cannot change.)
1903             *
1904             * <p> If the named class is not a top-level class, this invocation will
1905             * have no effect on the actual assertion status of any class. </p>
1906             *
1907             * @param  className
1908             *         The fully qualified class name of the top-level class whose
1909             *         assertion status is to be set.
1910             *
1911             * @param  enabled
1912             *         <tt>true</tt> if the named class is to have assertions
1913             *         enabled when (and if) it is initialized, <tt>false</tt> if the
1914             *         class is to have assertions disabled.
1915             *
1916             * @since  1.4
1917             */
1918            public synchronized void setClassAssertionStatus(String className,
1919                    boolean enabled) {
1920                if (classAssertionStatus == null)
1921                    initializeJavaAssertionMaps();
1922
1923                classAssertionStatus.put(className, Boolean.valueOf(enabled));
1924            }
1925
1926            /**
1927             * Sets the default assertion status for this class loader to
1928             * <tt>false</tt> and discards any package defaults or class assertion
1929             * status settings associated with the class loader.  This method is
1930             * provided so that class loaders can be made to ignore any command line or
1931             * persistent assertion status settings and "start with a clean slate."
1932             * </p>
1933             *
1934             * @since  1.4
1935             */
1936            public synchronized void clearAssertionStatus() {
1937                /*
1938                 * Whether or not "Java assertion maps" are initialized, set
1939                 * them to empty maps, effectively ignoring any present settings.
1940                 */
1941                classAssertionStatus = new HashMap();
1942                packageAssertionStatus = new HashMap();
1943
1944                defaultAssertionStatus = false;
1945            }
1946
1947            /**
1948             * Returns the assertion status that would be assigned to the specified
1949             * class if it were to be initialized at the time this method is invoked.
1950             * If the named class has had its assertion status set, the most recent
1951             * setting will be returned; otherwise, if any package default assertion
1952             * status pertains to this class, the most recent setting for the most
1953             * specific pertinent package default assertion status is returned;
1954             * otherwise, this class loader's default assertion status is returned.
1955             * </p>
1956             *
1957             * @param  className
1958             *         The fully qualified class name of the class whose desired
1959             *         assertion status is being queried.
1960             *
1961             * @return  The desired assertion status of the specified class.
1962             *
1963             * @see  #setClassAssertionStatus(String, boolean)
1964             * @see  #setPackageAssertionStatus(String, boolean)
1965             * @see  #setDefaultAssertionStatus(boolean)
1966             *
1967             * @since  1.4
1968             */
1969            synchronized boolean desiredAssertionStatus(String className) {
1970                Boolean result;
1971
1972                // assert classAssertionStatus   != null;
1973                // assert packageAssertionStatus != null;
1974
1975                // Check for a class entry
1976                result = (Boolean) classAssertionStatus.get(className);
1977                if (result != null)
1978                    return result.booleanValue();
1979
1980                // Check for most specific package entry
1981                int dotIndex = className.lastIndexOf(".");
1982                if (dotIndex < 0) { // default package
1983                    result = (Boolean) packageAssertionStatus.get(null);
1984                    if (result != null)
1985                        return result.booleanValue();
1986                }
1987                while (dotIndex > 0) {
1988                    className = className.substring(0, dotIndex);
1989                    result = (Boolean) packageAssertionStatus.get(className);
1990                    if (result != null)
1991                        return result.booleanValue();
1992                    dotIndex = className.lastIndexOf(".", dotIndex - 1);
1993                }
1994
1995                // Return the classloader default
1996                return defaultAssertionStatus;
1997            }
1998
1999            // Set up the assertions with information provided by the VM.
2000            private void initializeJavaAssertionMaps() {
2001                // assert Thread.holdsLock(this);
2002
2003                classAssertionStatus = new HashMap();
2004                packageAssertionStatus = new HashMap();
2005                AssertionStatusDirectives directives = retrieveDirectives();
2006
2007                for (int i = 0; i < directives.classes.length; i++)
2008                    classAssertionStatus.put(directives.classes[i], Boolean
2009                            .valueOf(directives.classEnabled[i]));
2010
2011                for (int i = 0; i < directives.packages.length; i++)
2012                    packageAssertionStatus.put(directives.packages[i], Boolean
2013                            .valueOf(directives.packageEnabled[i]));
2014
2015                defaultAssertionStatus = directives.deflt;
2016            }
2017
2018            // Retrieves the assertion directives from the VM.
2019            private static native AssertionStatusDirectives retrieveDirectives();
2020        }
2021
2022        class SystemClassLoaderAction implements  PrivilegedExceptionAction {
2023            private ClassLoader parent;
2024
2025            SystemClassLoaderAction(ClassLoader parent) {
2026                this .parent = parent;
2027            }
2028
2029            public Object run() throws Exception {
2030                ClassLoader sys;
2031                Constructor ctor;
2032                Class c;
2033                Class cp[] = { ClassLoader.class };
2034                Object params[] = { parent };
2035
2036                String cls = System.getProperty("java.system.class.loader");
2037                if (cls == null) {
2038                    return parent;
2039                }
2040
2041                c = Class.forName(cls, true, parent);
2042                ctor = c.getDeclaredConstructor(cp);
2043                sys = (ClassLoader) ctor.newInstance(params);
2044                Thread.currentThread().setContextClassLoader(sys);
2045                return sys;
2046            }
2047        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.