KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > lang > ClassLoader


1 /*
2  * @(#)ClassLoader.java 1.186 04/08/02
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package java.lang;
8
9 import java.io.InputStream JavaDoc;
10 import java.io.IOException JavaDoc;
11 import java.io.File JavaDoc;
12 import java.lang.reflect.Constructor JavaDoc;
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.net.MalformedURLException JavaDoc;
15 import java.net.URL JavaDoc;
16 import java.security.AccessController JavaDoc;
17 import java.security.AccessControlContext JavaDoc;
18 import java.security.CodeSource JavaDoc;
19 import java.security.Policy JavaDoc;
20 import java.security.PrivilegedAction JavaDoc;
21 import java.security.PrivilegedActionException JavaDoc;
22 import java.security.PrivilegedExceptionAction JavaDoc;
23 import java.security.ProtectionDomain JavaDoc;
24 import java.util.Enumeration JavaDoc;
25 import java.util.Hashtable JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Set JavaDoc;
29 import java.util.Stack JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Vector JavaDoc;
32 import sun.misc.ClassFileTransformer;
33 import sun.misc.CompoundEnumeration;
34 import sun.misc.Resource;
35 import sun.misc.URLClassPath;
36 import sun.misc.VM;
37 import sun.reflect.Reflection;
38 import sun.security.util.SecurityConstants;
39
40 /**
41  * A class loader is an object that is responsible for loading classes. The
42  * class <tt>ClassLoader</tt> is an abstract class. Given the <a
43  * HREF="#name">binary name</a> of a class, a class loader should attempt to
44  * locate or generate data that constitutes a definition for the class. A
45  * typical strategy is to transform the name into a file name and then read a
46  * "class file" of that name from a file system.
47  *
48  * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
49  * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
50  * it.
51  *
52  * <p> <tt>Class</tt> objects for array classes are not created by class
53  * loaders, but are created automatically as required by the Java runtime.
54  * The class loader for an array class, as returned by {@link
55  * Class#getClassLoader()} is the same as the class loader for its element
56  * type; if the element type is a primitive type, then the array class has no
57  * class loader.
58  *
59  * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
60  * extend the manner in which the Java virtual machine dynamically loads
61  * classes.
62  *
63  * <p> Class loaders may typically be used by security managers to indicate
64  * security domains.
65  *
66  * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
67  * classes and resources. Each instance of <tt>ClassLoader</tt> has an
68  * associated parent class loader. When requested to find a class or
69  * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
70  * class or resource to its parent class loader before attempting to find the
71  * class or resource itself. The virtual machine's built-in class loader,
72  * called the "bootstrap class loader", does not itself have a parent but may
73  * serve as the parent of a <tt>ClassLoader</tt> instance.
74  *
75  * <p> Normally, the Java virtual machine loads classes from the local file
76  * system in a platform-dependent manner. For example, on UNIX systems, the
77  * virtual machine loads classes from the directory defined by the
78  * <tt>CLASSPATH</tt> environment variable.
79  *
80  * <p> However, some classes may not originate from a file; they may originate
81  * from other sources, such as the network, or they could be constructed by an
82  * application. The method {@link #defineClass(String, byte[], int, int)
83  * <tt>defineClass</tt>} converts an array of bytes into an instance of class
84  * <tt>Class</tt>. Instances of this newly defined class can be created using
85  * {@link Class#newInstance <tt>Class.newInstance</tt>}.
86  *
87  * <p> The methods and constructors of objects created by a class loader may
88  * reference other classes. To determine the class(es) referred to, the Java
89  * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
90  * the class loader that originally created the class.
91  *
92  * <p> For example, an application could create a network class loader to
93  * download class files from a server. Sample code might look like:
94  *
95  * <blockquote><pre>
96  * ClassLoader loader&nbsp;= new NetworkClassLoader(host,&nbsp;port);
97  * Object main&nbsp;= loader.loadClass("Main", true).newInstance();
98  * &nbsp;.&nbsp;.&nbsp;.
99  * </pre></blockquote>
100  *
101  * <p> The network class loader subclass must define the methods {@link
102  * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
103  * from the network. Once it has downloaded the bytes that make up the class,
104  * it should use the method {@link #defineClass <tt>defineClass</tt>} to
105  * create a class instance. A sample implementation is:
106  *
107  * <blockquote><pre>
108  * class NetworkClassLoader extends ClassLoader {
109  * String host;
110  * int port;
111  *
112  * public Class findClass(String name) {
113  * byte[] b = loadClassData(name);
114  * return defineClass(name, b, 0, b.length);
115  * }
116  *
117  * private byte[] loadClassData(String name) {
118  * // load the class data from the connection
119  * &nbsp;.&nbsp;.&nbsp;.
120  * }
121  * }
122  * </pre></blockquote>
123  *
124  * <h4> <a name="name">Binary names</a> </h4>
125  *
126  * <p> Any class name provided as a {@link String} parameter to methods in
127  * <tt>ClassLoader</tt> must be a binary name as defined by the <a
128  * HREF="http://java.sun.com/docs/books/jls/">Java Language Specification</a>.
129  *
130  * <p> Examples of valid class names include:
131  * <blockquote><pre>
132  * "java.lang.String"
133  * "javax.swing.JSpinner$DefaultEditor"
134  * "java.security.KeyStore$Builder$FileBuilder$1"
135  * "java.net.URLClassLoader$3$1"
136  * </pre></blockquote>
137  *
138  * @version 1.186, 08/02/04
139  * @see #resolveClass(Class)
140  * @since 1.0
141  */

142 public abstract class ClassLoader {
143
144     private static native void registerNatives();
145     static {
146         registerNatives();
147     }
148
149     // If initialization succeed this is set to true and security checks will
150
// succeed. Otherwise the object is not initialized and the object is
151
// useless.
152
private boolean initialized = false;
153
154     // The parent class loader for delegation
155
private ClassLoader JavaDoc parent;
156
157     // Hashtable that maps packages to certs
158
private Hashtable JavaDoc package2certs = new Hashtable JavaDoc(11);
159
160     // Shared among all packages with unsigned classes
161
java.security.cert.Certificate JavaDoc[] nocerts;
162
163     // The classes loaded by this class loader. The only purpose of this table
164
// is to keep the classes from being GC'ed until the loader is GC'ed.
165
private Vector JavaDoc classes = new Vector JavaDoc();
166
167     // The initiating protection domains for all classes loaded by this loader
168
private Set JavaDoc domains = new HashSet JavaDoc();
169
170     // Invoked by the VM to record every loaded class with this loader.
171
void addClass(Class JavaDoc c) {
172         classes.addElement(c);
173     }
174
175     // The packages defined in this class loader. Each package name is mapped
176
// to its corresponding Package object.
177
private HashMap JavaDoc packages = new HashMap JavaDoc();
178
179     /**
180      * Creates a new class loader using the specified parent class loader for
181      * delegation.
182      *
183      * <p> If there is a security manager, its {@link
184      * SecurityManager#checkCreateClassLoader()
185      * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
186      * a security exception. </p>
187      *
188      * @param parent
189      * The parent class loader
190      *
191      * @throws SecurityException
192      * If a security manager exists and its
193      * <tt>checkCreateClassLoader</tt> method doesn't allow creation
194      * of a new class loader.
195      *
196      * @since 1.2
197      */

198     protected ClassLoader(ClassLoader JavaDoc parent) {
199     SecurityManager JavaDoc security = System.getSecurityManager();
200     if (security != null) {
201         security.checkCreateClassLoader();
202     }
203     this.parent = parent;
204     initialized = true;
205     }
206
207     /**
208      * Creates a new class loader using the <tt>ClassLoader</tt> returned by
209      * the method {@link #getSystemClassLoader()
210      * <tt>getSystemClassLoader()</tt>} as the parent class loader.
211      *
212      * <p> If there is a security manager, its {@link
213      * SecurityManager#checkCreateClassLoader()
214      * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
215      * a security exception. </p>
216      *
217      * @throws SecurityException
218      * If a security manager exists and its
219      * <tt>checkCreateClassLoader</tt> method doesn't allow creation
220      * of a new class loader.
221      */

222     protected ClassLoader() {
223     SecurityManager JavaDoc security = System.getSecurityManager();
224     if (security != null) {
225         security.checkCreateClassLoader();
226     }
227     this.parent = getSystemClassLoader();
228     initialized = true;
229     }
230
231
232     // -- Class --
233

234     /**
235      * Loads the class with the specified <a HREF="#name">binary name</a>.
236      * This method searches for classes in the same manner as the {@link
237      * #loadClass(String, boolean)} method. It is invoked by the Java virtual
238      * machine to resolve class references. Invoking this method is equivalent
239      * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
240      * false)</tt>}. </p>
241      *
242      * @param name
243      * The <a HREF="#name">binary name</a> of the class
244      *
245      * @return The resulting <tt>Class</tt> object
246      *
247      * @throws ClassNotFoundException
248      * If the class was not found
249      */

250     public Class JavaDoc<?> loadClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
251     return loadClass(name, false);
252     }
253
254     /**
255      * Loads the class with the specified <a HREF="#name">binary name</a>. The
256      * default implementation of this method searches for classes in the
257      * following order:
258      *
259      * <p><ol>
260      *
261      * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
262      * has already been loaded. </p></li>
263      *
264      * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
265      * on the parent class loader. If the parent is <tt>null</tt> the class
266      * loader built-in to the virtual machine is used, instead. </p></li>
267      *
268      * <li><p> Invoke the {@link #findClass(String)} method to find the
269      * class. </p></li>
270      *
271      * </ol>
272      *
273      * <p> If the class was found using the above steps, and the
274      * <tt>resolve</tt> flag is true, this method will then invoke the {@link
275      * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
276      *
277      * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
278      * #findClass(String)}, rather than this method. </p>
279      *
280      * @param name
281      * The <a HREF="#name">binary name</a> of the class
282      *
283      * @param resolve
284      * If <tt>true</tt> then resolve the class
285      *
286      * @return The resulting <tt>Class</tt> object
287      *
288      * @throws ClassNotFoundException
289      * If the class could not be found
290      */

291     protected synchronized Class JavaDoc<?> loadClass(String JavaDoc name, boolean resolve)
292     throws ClassNotFoundException JavaDoc
293     {
294     // First, check if the class has already been loaded
295
Class JavaDoc c = findLoadedClass(name);
296     if (c == null) {
297         try {
298         if (parent != null) {
299             c = parent.loadClass(name, false);
300         } else {
301             c = findBootstrapClass0(name);
302         }
303         } catch (ClassNotFoundException JavaDoc e) {
304             // If still not found, then invoke findClass in order
305
// to find the class.
306
c = findClass(name);
307         }
308     }
309     if (resolve) {
310         resolveClass(c);
311     }
312     return c;
313     }
314
315     // This method is invoked by the virtual machine to load a class.
316
private synchronized Class JavaDoc loadClassInternal(String JavaDoc name)
317     throws ClassNotFoundException JavaDoc
318     {
319     return loadClass(name);
320     }
321
322     private void checkPackageAccess(Class JavaDoc cls, ProtectionDomain JavaDoc pd) {
323     final SecurityManager JavaDoc sm = System.getSecurityManager();
324     if (sm != null) {
325         final String JavaDoc name = cls.getName();
326             final int i = name.lastIndexOf('.');
327         if (i != -1) {
328                 AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
329                     public Object JavaDoc run() {
330                 sm.checkPackageAccess(name.substring(0, i));
331                 return null;
332                     }
333                 }, new AccessControlContext JavaDoc(new ProtectionDomain JavaDoc[] {pd}));
334         }
335     }
336     domains.add(pd);
337     }
338
339     /**
340      * Finds the class with the specified <a HREF="#name">binary name</a>.
341      * This method should be overridden by class loader implementations that
342      * follow the delegation model for loading classes, and will be invoked by
343      * the {@link #loadClass <tt>loadClass</tt>} method after checking the
344      * parent class loader for the requested class. The default implementation
345      * throws a <tt>ClassNotFoundException</tt>. </p>
346      *
347      * @param name
348      * The <a HREF="#name">binary name</a> of the class
349      *
350      * @return The resulting <tt>Class</tt> object
351      *
352      * @throws ClassNotFoundException
353      * If the class could not be found
354      *
355      * @since 1.2
356      */

357     protected Class JavaDoc<?> findClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
358     throw new ClassNotFoundException JavaDoc(name);
359     }
360
361     /**
362      * Converts an array of bytes into an instance of class <tt>Class</tt>.
363      * Before the <tt>Class</tt> can be used it must be resolved. This method
364      * is deprecated in favor of the version that takes a <a
365      * HREF="#name">binary name</a> as its first argument, and is more secure.
366      *
367      * @param b
368      * The bytes that make up the class data. The bytes in positions
369      * <tt>off</tt> through <tt>off+len-1</tt> should have the format
370      * of a valid class file as defined by the <a
371      * HREF="http://java.sun.com/docs/books/vmspec/">Java Virtual
372      * Machine Specification</a>.
373      *
374      * @param off
375      * The start offset in <tt>b</tt> of the class data
376      *
377      * @param len
378      * The length of the class data
379      *
380      * @return The <tt>Class</tt> object that was created from the specified
381      * class data
382      *
383      * @throws ClassFormatError
384      * If the data did not contain a valid class
385      *
386      * @throws IndexOutOfBoundsException
387      * If either <tt>off</tt> or <tt>len</tt> is negative, or if
388      * <tt>off+len</tt> is greater than <tt>b.length</tt>.
389      *
390      * @see #loadClass(String, boolean)
391      * @see #resolveClass(Class)
392      *
393      * @deprecated Replaced by {@link #defineClass(String, byte[], int, int)
394      * defineClass(String, byte[], int, int)}
395      */

396     @Deprecated JavaDoc
397     protected final Class JavaDoc<?> defineClass(byte[] b, int off, int len)
398     throws ClassFormatError JavaDoc
399     {
400     return defineClass(null, b, off, len, null);
401     }
402
403     /**
404      * Converts an array of bytes into an instance of class <tt>Class</tt>.
405      * Before the <tt>Class</tt> can be used it must be resolved.
406      *
407      * <p> This method assigns a default {@link java.security.ProtectionDomain
408      * <tt>ProtectionDomain</tt>} to the newly defined class. The
409      * <tt>ProtectionDomain</tt> is effectively granted the same set of
410      * permissions returned when {@link
411      * java.security.Policy#getPermissions(java.security.CodeSource)
412      * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>}
413      * is invoked. The default domain is created on the first invocation of
414      * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>},
415      * and re-used on subsequent invocations.
416      *
417      * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use
418      * the {@link #defineClass(String, byte[], int, int,
419      * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a
420      * <tt>ProtectionDomain</tt> as one of its arguments. </p>
421      *
422      * @param name
423      * The expected <a HREF="#name">binary name</a> of the class, or
424      * <tt>null</tt> if not known
425      *
426      * @param b
427      * The bytes that make up the class data. The bytes in positions
428      * <tt>off</tt> through <tt>off+len-1</tt> should have the format
429      * of a valid class file as defined by the <a
430      * HREF="http://java.sun.com/docs/books/vmspec/">Java Virtual
431      * Machine Specification</a>.
432      *
433      * @param off
434      * The start offset in <tt>b</tt> of the class data
435      *
436      * @param len
437      * The length of the class data
438      *
439      * @return The <tt>Class</tt> object that was created from the specified
440      * class data.
441      *
442      * @throws ClassFormatError
443      * If the data did not contain a valid class
444      *
445      * @throws IndexOutOfBoundsException
446      * If either <tt>off</tt> or <tt>len</tt> is negative, or if
447      * <tt>off+len</tt> is greater than <tt>b.length</tt>.
448      *
449      * @throws SecurityException
450      * If an attempt is made to add this class to a package that
451      * contains classes that were signed by a different set of
452      * certificates than this class (which is unsigned), or if
453      * <tt>name</tt> begins with "<tt>java.</tt>".
454      *
455      * @see #loadClass(String, boolean)
456      * @see #resolveClass(Class)
457      * @see java.security.CodeSource
458      * @see java.security.SecureClassLoader
459      *
460      * @since 1.1
461      */

462     protected final Class JavaDoc<?> defineClass(String JavaDoc name, byte[] b, int off, int len)
463     throws ClassFormatError JavaDoc
464     {
465     return defineClass(name, b, off, len, null);
466     }
467
468     /* Determine protection domain, and check that:
469         - not define java.* class,
470     - signer of this class matches signers for the rest of the classes in package.
471     */

472     private ProtectionDomain JavaDoc preDefineClass(String JavaDoc name,
473                         ProtectionDomain JavaDoc protectionDomain)
474     {
475     if (!checkName(name))
476         throw new NoClassDefFoundError JavaDoc("IllegalName: " + name);
477
478     if ((name != null) && name.startsWith("java.")) {
479         throw new SecurityException JavaDoc("Prohibited package name: " +
480                     name.substring(0, name.lastIndexOf('.')));
481     }
482     if (protectionDomain == null) {
483         protectionDomain = getDefaultDomain();
484     }
485
486     if (name != null)
487         checkCerts(name, protectionDomain.getCodeSource());
488
489     return protectionDomain;
490     }
491
492     private String JavaDoc defineClassSourceLocation(ProtectionDomain JavaDoc protectionDomain)
493     {
494     CodeSource JavaDoc cs = protectionDomain.getCodeSource();
495     String JavaDoc source = null;
496     if (cs != null && cs.getLocation() != null) {
497         source = cs.getLocation().toString();
498     }
499     return source;
500     }
501
502     private Class JavaDoc defineTransformedClass(String JavaDoc name, byte[] b, int off, int len,
503                      ProtectionDomain JavaDoc protectionDomain,
504                      ClassFormatError JavaDoc cfe, String JavaDoc source)
505       throws ClassFormatError JavaDoc
506     {
507         // Class format error - try to transform the bytecode and
508
// define the class again
509
//
510
Object JavaDoc[] transformers = ClassFileTransformer.getTransformers();
511     Class JavaDoc c = null;
512
513     for (int i = 0; transformers != null && i < transformers.length; i++) {
514         try {
515           // Transform byte code using transformer
516
byte[] tb = ((ClassFileTransformer) transformers[i]).transform(b, off, len);
517           c = defineClass1(name, tb, 0, tb.length, protectionDomain, source);
518           break;
519         } catch (ClassFormatError JavaDoc cfe2) {
520           // If ClassFormatError occurs, try next transformer
521
}
522     }
523
524     // Rethrow original ClassFormatError if unable to transform
525
// bytecode to well-formed
526
//
527
if (c == null)
528         throw cfe;
529
530     return c;
531     }
532
533     private void postDefineClass(Class JavaDoc c, ProtectionDomain JavaDoc protectionDomain)
534     {
535     if (protectionDomain.getCodeSource() != null) {
536         java.security.cert.Certificate JavaDoc certs[] =
537         protectionDomain.getCodeSource().getCertificates();
538         if (certs != null)
539         setSigners(c, certs);
540     }
541     }
542
543     /**
544      * Converts an array of bytes into an instance of class <tt>Class</tt>,
545      * with an optional <tt>ProtectionDomain</tt>. If the domain is
546      * <tt>null</tt>, then a default domain will be assigned to the class as
547      * specified in the documentation for {@link #defineClass(String, byte[],
548      * int, int)}. Before the class can be used it must be resolved.
549      *
550      * <p> The first class defined in a package determines the exact set of
551      * certificates that all subsequent classes defined in that package must
552      * contain. The set of certificates for a class is obtained from the
553      * {@link java.security.CodeSource <tt>CodeSource</tt>} within the
554      * <tt>ProtectionDomain</tt> of the class. Any classes added to that
555      * package must contain the same set of certificates or a
556      * <tt>SecurityException</tt> will be thrown. Note that if
557      * <tt>name</tt> is <tt>null</tt>, this check is not performed.
558      * You should always pass in the <a HREF="#name">binary name</a> of the
559      * class you are defining as well as the bytes. This ensures that the
560      * class you are defining is indeed the class you think it is.
561      *
562      * <p> The specified <tt>name</tt> cannot begin with "<tt>java.</tt>", since
563      * all classes in the "<tt>java.*</tt> packages can only be defined by the
564      * bootstrap class loader. If <tt>name</tt> is not <tt>null</tt>, it
565      * must be equal to the <a HREF="#name">binary name</a> of the class
566      * specified by the byte array "<tt>b</tt>", otherwise a {@link
567      * <tt>NoClassDefFoundError</tt>} will be thrown. </p>
568      *
569      * @param name
570      * The expected <a HREF="#name">binary name</a> of the class, or
571      * <tt>null</tt> if not known
572      *
573      * @param b
574      * The bytes that make up the class data. The bytes in positions
575      * <tt>off</tt> through <tt>off+len-1</tt> should have the format
576      * of a valid class file as defined by the <a
577      * HREF="http://java.sun.com/docs/books/vmspec/">Java Virtual
578      * Machine Specification</a>.
579      *
580      * @param off
581      * The start offset in <tt>b</tt> of the class data
582      *
583      * @param len
584      * The length of the class data
585      *
586      * @param protectionDomain
587      * The ProtectionDomain of the class
588      *
589      * @return The <tt>Class</tt> object created from the data,
590      * and optional <tt>ProtectionDomain</tt>.
591      *
592      * @throws ClassFormatError
593      * If the data did not contain a valid class
594      *
595      * @throws NoClassDefFoundError
596      * If <tt>name</tt> is not equal to the <a HREF="#name">binary
597      * name</a> of the class specified by <tt>b</tt>
598      *
599      * @throws IndexOutOfBoundsException
600      * If either <tt>off</tt> or <tt>len</tt> is negative, or if
601      * <tt>off+len</tt> is greater than <tt>b.length</tt>.
602      *
603      * @throws SecurityException
604      * If an attempt is made to add this class to a package that
605      * contains classes that were signed by a different set of
606      * certificates than this class, or if <tt>name</tt> begins with
607      * "<tt>java.</tt>".
608      */

609     protected final Class JavaDoc<?> defineClass(String JavaDoc name, byte[] b, int off, int len,
610                      ProtectionDomain JavaDoc protectionDomain)
611     throws ClassFormatError JavaDoc
612     {
613     check();
614     protectionDomain = preDefineClass(name, protectionDomain);
615
616     Class JavaDoc c = null;
617         String JavaDoc source = defineClassSourceLocation(protectionDomain);
618
619     try {
620         c = defineClass1(name, b, off, len, protectionDomain, source);
621     } catch (ClassFormatError JavaDoc cfe) {
622         c = defineTransformedClass(name, b, off, len, protectionDomain, cfe, source);
623     }
624
625     postDefineClass(c, protectionDomain);
626     return c;
627     }
628
629     /**
630      * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>}
631      * into an instance of class <tt>Class</tt>,
632      * with an optional <tt>ProtectionDomain</tt>. If the domain is
633      * <tt>null</tt>, then a default domain will be assigned to the class as
634      * specified in the documentation for {@link #defineClass(String, byte[],
635      * int, int)}. Before the class can be used it must be resolved.
636      *
637      * <p>The rules about the first class defined in a package determining the set of
638      * certificates for the package, and the restrictions on class names are identical
639      * to those specified in the documentation for {@link #defineClass(String, byte[],
640      * int, int, ProtectionDomain)}.
641      *
642      * <p> An invocation of this method of the form
643      * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>
644      * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
645      * result as the statements
646      *
647      * <blockquote><tt>
648      * ...<br>
649      * byte[] temp = new byte[</tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#remaining
650      * remaining}()];<br>
651      * </tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#get(byte[])
652      * get}(temp);<br>
653      * return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
654      * </tt><i>cl</i><tt>.defineClass}(</tt><i>name</i><tt>, temp, 0, temp.length, </tt><i>pd</i><tt>);<br>
655      * </tt></blockquote>
656      *
657      * @param name
658      * The expected <a HREF="#name">binary name</a. of the class, or
659      * <tt>null</tt> if not known
660      *
661      * @param b
662      * The bytes that make up the class data. The bytes from positions
663      * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1 </tt>
664      * should have the format of a valid class file as defined by the <a
665      * HREF="http://java.sun.com/docs/books/vmspec/">Java Virtual
666      * Machine Specification</a>.
667      *
668      * @param protectionDomain
669      * The ProtectionDomain of the class, or <tt>null</tt>.
670      *
671      * @return The <tt>Class</tt> object created from the data,
672      * and optional <tt>ProtectionDomain</tt>.
673      *
674      * @throws ClassFormatError
675      * If the data did not contain a valid class.
676      *
677      * @throws NoClassDefFoundError
678      * If <tt>name</tt> is not equal to the <a HREF="#name">binary
679      * name</a> of the class specified by <tt>b</tt>
680      *
681      * @throws SecurityException
682      * If an attempt is made to add this class to a package that
683      * contains classes that were signed by a different set of
684      * certificates than this class, or if <tt>name</tt> begins with
685      * "<tt>java.</tt>".
686      *
687      * @see #defineClass(String, byte[], int, int, ProtectionDomain)
688      *
689      * @since 1.5
690      */

691     protected final Class JavaDoc<?> defineClass(String JavaDoc name, java.nio.ByteBuffer JavaDoc b,
692                      ProtectionDomain JavaDoc protectionDomain)
693     throws ClassFormatError JavaDoc
694     {
695     check();
696
697     int len = b.remaining();
698
699     // Use byte[] if not a direct ByteBufer:
700
if (!b.isDirect()) {
701         if (b.hasArray()) {
702         return defineClass(name, b.array(),
703                    b.position() + b.arrayOffset(), len,
704                    protectionDomain);
705         } else {
706         // no array, or read-only array
707
byte[] tb = new byte[len];
708         b.get(tb); // get bytes out of byte buffer.
709
return defineClass(name, tb, 0, len, protectionDomain);
710         }
711     }
712
713         protectionDomain = preDefineClass(name, protectionDomain);
714
715     Class JavaDoc c = null;
716     String JavaDoc source = defineClassSourceLocation(protectionDomain);
717
718     try {
719         c = defineClass2(name, b, b.position(), len, protectionDomain, source);
720     } catch (ClassFormatError JavaDoc cfe) {
721         byte[] tb = new byte[len];
722         b.get(tb); // get bytes out of byte buffer.
723
c = defineTransformedClass(name, tb, 0, len, protectionDomain, cfe, source);
724     }
725
726     postDefineClass(c, protectionDomain);
727     return c;
728     }
729
730     private native Class JavaDoc defineClass0(String JavaDoc name, byte[] b, int off, int len,
731                                   ProtectionDomain JavaDoc pd);
732
733     private native Class JavaDoc defineClass1(String JavaDoc name, byte[] b, int off, int len,
734                                   ProtectionDomain JavaDoc pd, String JavaDoc source);
735
736     private native Class JavaDoc defineClass2(String JavaDoc name, java.nio.ByteBuffer JavaDoc b,
737                       int off, int len, ProtectionDomain JavaDoc pd,
738                       String JavaDoc source);
739
740     // true if the name is null or has the potential to be a valid binary name
741
private boolean checkName(String JavaDoc name) {
742     if ((name == null) || (name.length() == 0))
743         return true;
744     if ((name.indexOf('/') != -1)
745         || (!VM.allowArraySyntax() && (name.charAt(0) == '[')))
746         return false;
747     return true;
748     }
749
750     private synchronized void checkCerts(String JavaDoc name, CodeSource JavaDoc cs) {
751     int i = name.lastIndexOf('.');
752     String JavaDoc pname = (i == -1) ? "" : name.substring(0, i);
753     java.security.cert.Certificate JavaDoc[] pcerts =
754         (java.security.cert.Certificate JavaDoc[]) package2certs.get(pname);
755         if (pcerts == null) {
756         // first class in this package gets to define which
757
// certificates must be the same for all other classes
758
// in this package
759
if (cs != null) {
760         pcerts = cs.getCertificates();
761         }
762         if (pcerts == null) {
763         if (nocerts == null)
764             nocerts = new java.security.cert.Certificate JavaDoc[0];
765         pcerts = nocerts;
766         }
767         package2certs.put(pname, pcerts);
768     } else {
769         java.security.cert.Certificate JavaDoc[] certs = null;
770         if (cs != null) {
771         certs = cs.getCertificates();
772         }
773
774         if (!compareCerts(pcerts, certs)) {
775         throw new SecurityException JavaDoc("class \""+ name +
776                         "\"'s signer information does not match signer information of other classes in the same package");
777         }
778     }
779     }
780
781     /**
782      * check to make sure the certs for the new class (certs) are the same as
783      * the certs for the first class inserted in the package (pcerts)
784      */

785     private boolean compareCerts(java.security.cert.Certificate JavaDoc[] pcerts,
786                  java.security.cert.Certificate JavaDoc[] certs)
787     {
788     // certs can be null, indicating no certs.
789
if ((certs == null) || (certs.length == 0)) {
790         return pcerts.length == 0;
791     }
792
793     // the length must be the same at this point
794
if (certs.length != pcerts.length)
795         return false;
796
797     // go through and make sure all the certs in one array
798
// are in the other and vice-versa.
799
boolean match;
800     for (int i = 0; i < certs.length; i++) {
801         match = false;
802         for (int j = 0; j < pcerts.length; j++) {
803         if (certs[i].equals(pcerts[j])) {
804             match = true;
805             break;
806         }
807         }
808         if (!match) return false;
809     }
810
811     // now do the same for pcerts
812
for (int i = 0; i < pcerts.length; i++) {
813         match = false;
814         for (int j = 0; j < certs.length; j++) {
815         if (pcerts[i].equals(certs[j])) {
816             match = true;
817             break;
818         }
819         }
820         if (!match) return false;
821     }
822
823     return true;
824     }
825
826     /**
827      * Links the specified class. This (misleadingly named) method may be
828      * used by a class loader to link a class. If the class <tt>c</tt> has
829      * already been linked, then this method simply returns. Otherwise, the
830      * class is linked as described in the "Execution" chapter of the <a
831      * HREF="http://java.sun.com/docs/books/jls/">Java Language
832      * Specification</a>.
833      * </p>
834      *
835      * @param c
836      * The class to link
837      *
838      * @throws NullPointerException
839      * If <tt>c</tt> is <tt>null</tt>.
840      *
841      * @see #defineClass(String, byte[], int, int)
842      */

843     protected final void resolveClass(Class JavaDoc<?> c) {
844     check();
845     resolveClass0(c);
846     }
847
848     private native void resolveClass0(Class JavaDoc c);
849
850     /**
851      * Finds a class with the specified <a HREF="#name">binary name</a>,
852      * loading it if necessary.
853      *
854      * <p> This method loads the class through the system class loader (see
855      * {@link #getSystemClassLoader()}). The <tt>Class</tt> object returned
856      * might have more than one <tt>ClassLoader</tt> associated with it.
857      * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,
858      * because most class loaders need to override just {@link
859      * #findClass(String)}. </p>
860      *
861      * @param name
862      * The <a HREF="#name">binary name</a> of the class
863      *
864      * @return The <tt>Class</tt> object for the specified <tt>name</tt>
865      *
866      * @throws ClassNotFoundException
867      * If the class could not be found
868      *
869      * @see #ClassLoader(ClassLoader)
870      * @see #getParent()
871      */

872     protected final Class JavaDoc<?> findSystemClass(String JavaDoc name)
873     throws ClassNotFoundException JavaDoc
874     {
875     check();
876     ClassLoader JavaDoc system = getSystemClassLoader();
877     if (system == null) {
878         if (!checkName(name))
879         throw new ClassNotFoundException JavaDoc(name);
880         return findBootstrapClass(name);
881     }
882     return system.loadClass(name);
883     }
884
885     private Class JavaDoc findBootstrapClass0(String JavaDoc name)
886     throws ClassNotFoundException JavaDoc
887     {
888     check();
889     if (!checkName(name))
890         throw new ClassNotFoundException JavaDoc(name);
891     return findBootstrapClass(name);
892     }
893
894     private native Class JavaDoc findBootstrapClass(String JavaDoc name)
895     throws ClassNotFoundException JavaDoc;
896
897     // Check to make sure the class loader has been initialized.
898
private void check() {
899     if (!initialized) {
900         throw new SecurityException JavaDoc(