OSDN Git Service

2001-02-15 Anthony Green <green@redhat.com>
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / ClassLoader.java
1 // ClassLoader.java - Define policies for loading Java classes.
2
3 /* Copyright (C) 1998, 1999, 2000  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 package java.lang;
12
13 import java.io.InputStream;
14 import java.io.IOException;
15 import java.net.URL;
16 import java.net.URLConnection;
17 import java.util.Enumeration;
18 import java.util.Stack;
19
20 /**
21  * The class <code>ClassLoader</code> is intended to be subclassed by
22  * applications in order to describe new ways of loading classes,
23  * such as over the network.
24  *
25  * @author  Kresten Krab Thorup
26  */
27
28 public abstract class ClassLoader {
29
30   static private ClassLoader system;
31   private ClassLoader parent;
32
33   public ClassLoader getParent ()
34   {
35     /* FIXME: security */
36     return parent;
37   }
38     
39   public static native ClassLoader getSystemClassLoader ();
40
41   /**
42    * Creates a <code>ClassLoader</code> with no parent.
43    * @exception java.lang.SecurityException if not allowed
44    */
45   protected ClassLoader() 
46   {
47     this (null);
48   }
49
50   /**
51    * Creates a <code>ClassLoader</code> with the given parent.   
52    * The parent may be <code>null</code>.
53    * The only thing this 
54    * constructor does, is to call
55    * <code>checkCreateClassLoader</code> on the current 
56    * security manager. 
57    * @exception java.lang.SecurityException if not allowed
58    */
59   protected ClassLoader(ClassLoader parent) 
60   {
61     SecurityManager security = System.getSecurityManager ();
62     if (security != null)
63       security.checkCreateClassLoader ();
64     this.parent = parent;
65   }
66
67   /** 
68    * Loads and link the class by the given name.
69    * @param     name the name of the class.
70    * @return    the class loaded.
71    * @see       ClassLoader#loadClass(String,boolean)
72    * @exception java.lang.ClassNotFoundException 
73    */ 
74   public Class loadClass(String name) 
75     throws java.lang.ClassNotFoundException, java.lang.LinkageError
76   { 
77     return loadClass (name, false);
78   }
79
80   /** 
81    * Loads the class by the given name.  The default implementation
82    * will search for the class in the following order (similar to jdk 1.2)
83    * <ul>
84    *  <li> First <code>findLoadedClass</code>.
85    *  <li> If parent is non-null, <code>parent.loadClass</code>;
86    *       otherwise <code>findSystemClass</code>.
87    *  <li> <code>findClass</code>.
88    * </ul>
89    * If <code>link</code> is true, <code>resolveClass</code> is then
90    * called.  <p> Normally, this need not be overridden; override
91    * <code>findClass</code> instead.
92    * @param     name the name of the class.
93    * @param     link if the class should be linked.
94    * @return    the class loaded.
95    * @exception java.lang.ClassNotFoundException 
96    * @deprecated 
97    */ 
98   protected Class loadClass(String name, boolean link)
99     throws java.lang.ClassNotFoundException, java.lang.LinkageError
100   {
101     Class c = findLoadedClass (name);
102
103     if (c == null)
104       {
105         try {
106           if (parent != null)
107             return parent.loadClass (name, link);
108           else
109             c = findSystemClass (name);
110         } catch (ClassNotFoundException ex) {
111           /* ignore, we'll try findClass */;
112         }
113       }
114
115     if (c == null)
116       c = findClass (name);
117
118     if (c == null)
119       throw new ClassNotFoundException (name);
120
121     if (link)
122       resolveClass (c);
123
124     return c;
125   }
126
127   /** Find a class.  This should be overridden by subclasses; the
128    *  default implementation throws ClassNotFoundException.
129    *
130    * @param name Name of the class to find.
131    * @return     The class found.
132    * @exception  java.lang.ClassNotFoundException
133    */
134   protected Class findClass (String name)
135     throws ClassNotFoundException
136   {
137     throw new ClassNotFoundException (name);
138   }
139
140   /** 
141    * Defines a class, given the class-data.  According to the JVM, this
142    * method should not be used; instead use the variant of this method
143    * in which the name of the class being defined is specified
144    * explicitly.   
145    * <P>
146    * If the name of the class, as specified (implicitly) in the class
147    * data, denotes a class which has already been loaded by this class
148    * loader, an instance of
149    * <code>java.lang.ClassNotFoundException</code> will be thrown.
150    *
151    * @param     data    bytes in class file format.
152    * @param     off     offset to start interpreting data.
153    * @param     len     length of data in class file.
154    * @return    the class defined.
155    * @exception java.lang.ClassNotFoundException 
156    * @exception java.lang.LinkageError
157    * @see ClassLoader#defineClass(String,byte[],int,int) */
158   protected final Class defineClass(byte[] data, int off, int len) 
159     throws ClassFormatError
160   {
161     return defineClass (null, data, off, len);
162   }
163
164   /** 
165    * Defines a class, given the class-data.  This is preferable
166    * over <code>defineClass(byte[],off,len)</code> since it is more
167    * secure.  If the expected name does not match that of the class
168    * file, <code>ClassNotFoundException</code> is thrown.  If
169    * <code>name</code> denotes the name of an already loaded class, a
170    * <code>LinkageError</code> is thrown.
171    * <p>
172    * 
173    * FIXME: How do we assure that the class-file data is not being
174    * modified, simultaneously with the class loader running!?  If this
175    * was done in some very clever way, it might break security.  
176    * Right now I am thinking that defineclass should make sure never to
177    * read an element of this array more than once, and that that would
178    * assure the ``immutable'' appearance.  It is still to be determined
179    * if this is in fact how defineClass operates.
180    *
181    * @param     name    the expected name.
182    * @param     data    bytes in class file format.
183    * @param     off     offset to start interpreting data.
184    * @param     len     length of data in class file.
185    * @return    the class defined.
186    * @exception java.lang.ClassNotFoundException 
187    * @exception java.lang.LinkageError
188    */
189   protected final synchronized Class defineClass(String name,
190                                                  byte[] data,
191                                                  int off,
192                                                  int len)
193     throws ClassFormatError
194   {
195     if (data==null || data.length < off+len || off<0 || len<0)
196       throw new ClassFormatError ("arguments to defineClass "
197                                   + "are meaningless");
198
199     // as per 5.3.5.1
200     if (name != null  &&  findLoadedClass (name) != null)
201       throw new java.lang.LinkageError ("class " 
202                                         + name 
203                                         + " already loaded");
204
205     try {
206       // Since we're calling into native code here, 
207       // we better make sure that any generated
208       // exception is to spec!
209
210       return defineClass0 (name, data, off, len);
211
212     } catch (ClassFormatError x) {
213       throw x;          // rethrow
214
215     } catch (java.lang.VirtualMachineError x) {
216       throw x;          // rethrow
217
218     } catch (java.lang.Throwable x) {
219       // This should never happen, or we are beyond spec.  
220       
221       throw new InternalError ("Unexpected exception "
222                                + "while defining class "
223                                + name + ": " 
224                                + x.toString ());
225     }
226   }
227
228   /** This is the entry point of defineClass into the native code */
229   private native Class defineClass0 (String name,
230                                      byte[] data,
231                                      int off,
232                                      int len)
233     throws ClassFormatError;
234
235
236   /** 
237    * Link the given class.  This will bring the class to a state where
238    * the class initializer can be run.  Linking involves the following
239    * steps: 
240    * <UL>
241    * <LI>  Prepare (allocate and internalize) the constant strings that
242    *       are used in this class.
243    * <LI>  Allocate storage for static fields, and define the layout
244    *       of instance fields.
245    * <LI>  Perform static initialization of ``static final'' int,
246    *       long, float, double and String fields for which there is a
247    *       compile-time constant initializer.
248    * <LI>  Create the internal representation of the ``vtable''.
249    * </UL>
250    * For <code>gcj</code>-compiled classes, only the first step is
251    * performed.  The compiler will have done the rest already.
252    * <P>
253    * This is called by the system automatically,
254    * as part of class initialization; there is no reason to ever call
255    * this method directly.  
256    * <P> 
257    * For historical reasons, this method has a name which is easily
258    * misunderstood.  Java classes are never ``resolved''.  Classes are
259    * linked; whereas method and field references are resolved.
260    *
261    * @param     clazz the class to link.
262    * @exception java.lang.LinkageError
263    */
264   protected final void resolveClass(Class clazz)
265     throws java.lang.LinkageError
266   {
267     resolveClass0(clazz);
268   }
269
270   static void resolveClass0(Class clazz)
271     throws java.lang.LinkageError
272   {
273     synchronized (clazz)
274       {
275         try {
276           linkClass0 (clazz);
277         } catch (Throwable x) {
278           markClassErrorState0 (clazz);
279
280           if (x instanceof Error)
281             throw (Error)x;
282           else    
283             throw new java.lang.InternalError
284               ("unexpected exception during linking: " + x);
285         }
286       }
287   }
288
289   /** Internal method.  Calls _Jv_PrepareClass and
290    * _Jv_PrepareCompiledClass.  This is only called from resolveClass.  */ 
291   private static native void linkClass0(Class clazz)
292     throws java.lang.LinkageError;
293
294   /** Internal method.  Marks the given clazz to be in an erroneous
295    * state, and calls notifyAll() on the class object.  This should only
296    * be called when the caller has the lock on the class object.  */
297   private static native void markClassErrorState0(Class clazz);
298
299
300   /** 
301    * Returns a class found in a system-specific way, typically
302    * via the <code>java.class.path</code> system property.  Loads the 
303    * class if necessary.
304    *
305    * @param     name the class to resolve.
306    * @return    the class loaded.
307    * @exception java.lang.LinkageError 
308    * @exception java.lang.ClassNotFoundException 
309    */
310   protected Class findSystemClass(String name) 
311     throws java.lang.ClassNotFoundException, java.lang.LinkageError
312   {
313     return getSystemClassLoader ().loadClass (name);
314   }
315
316   /*
317    * Does currently nothing.
318    */ 
319   protected final void setSigners(Class claz, Object[] signers) {
320     /* claz.setSigners (signers); */
321   }
322
323   /**
324    * If a class named <code>name</code> was previously loaded using
325    * this <code>ClassLoader</code>, then it is returned.  Otherwise
326    * it returns <code>null</code>.  (Unlike the JDK this is native,
327    * since we implement the class table internally.)
328    * @param     name  class to find.
329    * @return    the class loaded, or null.
330    */ 
331   protected native Class findLoadedClass(String name);
332
333   public static final InputStream getSystemResourceAsStream(String name) {
334     return getSystemClassLoader().getResourceAsStream (name);
335   }
336
337   public static final URL getSystemResource(String name) {
338     return getSystemClassLoader().getResource (name);
339   }
340
341   /**
342    *   Return an InputStream representing the resource name.  
343    *   This is essentially like 
344    *   <code>getResource(name).openStream()</code>, except
345    *   it masks out any IOException and returns null on failure.
346    * @param   name  resource to load
347    * @return  an InputStream, or null
348    * @see     java.lang.ClassLoader#getResource(String)
349    * @see     java.io.InputStream
350    */
351   public InputStream getResourceAsStream(String name) 
352   {
353     try {
354       URL res = getResource (name);
355       if (res == null) return null;
356       return res.openStream ();
357     } catch (java.io.IOException x) {
358       return null;
359     }
360   }
361  
362   /**
363    * Return an java.io.URL representing the resouce <code>name</code>.  
364    * The default implementation just returns <code>null</code>.
365    * @param   name  resource to load
366    * @return  a URL, or null if there is no such resource.
367    * @see     java.lang.ClassLoader#getResourceAsBytes(String)
368    * @see     java.lang.ClassLoader#getResourceAsStream(String)
369    * @see     java.io.URL
370    */
371   public URL getResource (String name) 
372   {
373     // The rules say search the parent class if non-null,
374     // otherwise search the built-in class loader (assumed to be
375     // the system ClassLoader).  If not found, call
376     // findResource().
377     URL result = null;
378
379     ClassLoader delegate = parent;
380
381     if (delegate == null)
382       delegate = getSystemClassLoader ();
383         
384     // Protect ourselves from looping.
385     if (this != delegate)
386       result = delegate.getResource (name);
387
388     if (result != null)
389       return result;
390     else
391       return findResource (name);
392   }
393
394   protected URL findResource (String name)
395   {
396     // Default to returning null.  Derived classes implement this.
397     return null;
398   }
399
400   public Enumeration getResources (String name) throws IOException
401   {
402     // The rules say search the parent class if non-null,
403     // otherwise search the built-in class loader (assumed to be
404     // the system ClassLoader).  If not found, call
405     // findResource().
406     Enumeration result = null;
407
408     ClassLoader delegate = parent;
409
410     if (delegate == null)
411       delegate = getSystemClassLoader ();
412         
413     // Protect ourselves from looping.
414     if (this != delegate)
415       result = delegate.getResources (name);
416
417     if (result != null)
418       return result;
419     else
420       return findResources (name);
421   }
422
423   protected Enumeration findResources (String name) throws IOException
424   {
425     // Default to returning null.  Derived classes implement this.
426     return null;
427   }
428 }