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

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » java.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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