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

Java Source Code / Java Documentation
1. JDK Core
2. JDK Modules
3. JDK Modules com.sun
4. JDK Modules com.sun.java
5. JDK Modules Platform
6. JDK Modules sun
7. Open Source Graphic Library
8. Open Source IDE Eclipse
9. Open Source J2EE
10. Open Source JBOSS
11. Open Source JDBC Driver
12. Open Source Library
13. Open Source Library Database
14. Open Source Net
15. Science
16. Sevlet Container
17. SUN GlassFish
18. Swing Library
19. Web Services apache cxf 2.0.1
20. Web Services AXIS2
21. XML
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Java Source Code / Java Documentation » 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:        }
w__ww_._j__a_v___a_2__s_._c__o___m
Home | Contact Us
Copyright 2003 - 07 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.