1 // ClassLoader.java - Define policies for loading Java classes.
3 /* Copyright (C) 1998, 1999, 2000 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
13 import java.io.InputStream;
14 import java.io.IOException;
16 import java.net.URLConnection;
17 import java.util.Enumeration;
18 import java.util.Stack;
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.
25 * @author Kresten Krab Thorup
28 public abstract class ClassLoader {
30 static private ClassLoader system;
31 private ClassLoader parent;
33 public ClassLoader getParent ()
39 public static native ClassLoader getSystemClassLoader ();
42 * Creates a <code>ClassLoader</code> with no parent.
43 * @exception java.lang.SecurityException if not allowed
45 protected ClassLoader()
51 * Creates a <code>ClassLoader</code> with the given parent.
52 * The parent may be <code>null</code>.
54 * constructor does, is to call
55 * <code>checkCreateClassLoader</code> on the current
57 * @exception java.lang.SecurityException if not allowed
59 protected ClassLoader(ClassLoader parent)
61 SecurityManager security = System.getSecurityManager ();
63 security.checkCreateClassLoader ();
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
74 public Class loadClass(String name)
75 throws java.lang.ClassNotFoundException, java.lang.LinkageError
77 return loadClass (name, false);
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)
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>.
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
98 protected Class loadClass(String name, boolean link)
99 throws java.lang.ClassNotFoundException, java.lang.LinkageError
101 Class c = findLoadedClass (name);
107 return parent.loadClass (name, link);
109 c = findSystemClass (name);
110 } catch (ClassNotFoundException ex) {
111 /* ignore, we'll try findClass */;
116 c = findClass (name);
119 throw new ClassNotFoundException (name);
127 /** Find a class. This should be overridden by subclasses; the
128 * default implementation throws ClassNotFoundException.
130 * @param name Name of the class to find.
131 * @return The class found.
132 * @exception java.lang.ClassNotFoundException
134 protected Class findClass (String name)
135 throws ClassNotFoundException
137 throw new ClassNotFoundException (name);
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
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.
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
161 return defineClass (null, data, off, len);
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.
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.
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
189 protected final synchronized Class defineClass(String name,
193 throws ClassFormatError
195 if (data==null || data.length < off+len || off<0 || len<0)
196 throw new ClassFormatError ("arguments to defineClass "
197 + "are meaningless");
200 if (name != null && findLoadedClass (name) != null)
201 throw new java.lang.LinkageError ("class "
203 + " already loaded");
206 // Since we're calling into native code here,
207 // we better make sure that any generated
208 // exception is to spec!
210 return defineClass0 (name, data, off, len);
212 } catch (ClassFormatError x) {
215 } catch (java.lang.VirtualMachineError x) {
218 } catch (java.lang.Throwable x) {
219 // This should never happen, or we are beyond spec.
221 throw new InternalError ("Unexpected exception "
222 + "while defining class "
228 /** This is the entry point of defineClass into the native code */
229 private native Class defineClass0 (String name,
233 throws ClassFormatError;
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
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''.
250 * For <code>gcj</code>-compiled classes, only the first step is
251 * performed. The compiler will have done the rest already.
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.
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.
261 * @param clazz the class to link.
262 * @exception java.lang.LinkageError
264 protected final void resolveClass(Class clazz)
265 throws java.lang.LinkageError
267 resolveClass0(clazz);
270 static void resolveClass0(Class clazz)
271 throws java.lang.LinkageError
277 } catch (Throwable x) {
278 markClassErrorState0 (clazz);
280 if (x instanceof Error)
283 throw new java.lang.InternalError
284 ("unexpected exception during linking: " + x);
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;
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);
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.
305 * @param name the class to resolve.
306 * @return the class loaded.
307 * @exception java.lang.LinkageError
308 * @exception java.lang.ClassNotFoundException
310 protected Class findSystemClass(String name)
311 throws java.lang.ClassNotFoundException, java.lang.LinkageError
313 return getSystemClassLoader ().loadClass (name);
317 * Does currently nothing.
319 protected final void setSigners(Class claz, Object[] signers) {
320 /* claz.setSigners (signers); */
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.
331 protected native Class findLoadedClass(String name);
333 public static final InputStream getSystemResourceAsStream(String name) {
334 return getSystemClassLoader().getResourceAsStream (name);
337 public static final URL getSystemResource(String name) {
338 return getSystemClassLoader().getResource (name);
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
351 public InputStream getResourceAsStream(String name)
354 URL res = getResource (name);
355 if (res == null) return null;
356 return res.openStream ();
357 } catch (java.io.IOException x) {
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)
371 public URL getResource (String name)
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
379 ClassLoader delegate = parent;
381 if (delegate == null)
382 delegate = getSystemClassLoader ();
384 // Protect ourselves from looping.
385 if (this != delegate)
386 result = delegate.getResource (name);
391 return findResource (name);
394 protected URL findResource (String name)
396 // Default to returning null. Derived classes implement this.
400 public Enumeration getResources (String name) throws IOException
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
406 Enumeration result = null;
408 ClassLoader delegate = parent;
410 if (delegate == null)
411 delegate = getSystemClassLoader ();
413 // Protect ourselves from looping.
414 if (this != delegate)
415 result = delegate.getResources (name);
420 return findResources (name);
423 protected Enumeration findResources (String name) throws IOException
425 // Default to returning null. Derived classes implement this.