1 // ClassLoader.java - Define policies for loading Java classes.
3 /* Copyright (C) 1998, 1999 Cygnus Solutions
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;
15 import java.net.URLConnection;
16 import java.util.Stack;
19 * The class <code>ClassLoader</code> is intended to be subclassed by
20 * applications in order to describe new ways of loading classes,
21 * such as over the network.
23 * @author Kresten Krab Thorup
26 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
27 * Status: Just a stub; not useful at all.
30 public abstract class ClassLoader {
32 static private ClassLoader system;
34 private static native ClassLoader getVMClassLoader0 ();
36 static public ClassLoader getSystemClassLoader () {
38 system = getVMClassLoader0 ();
43 * Creates a <code>ClassLoader</code>. The only thing this
44 * constructor does, is to call
45 * <code>checkCreateClassLoader</code> on the current
47 * @exception java.lang.SecurityException if not allowed
49 protected ClassLoader()
51 SecurityManager security = System.getSecurityManager ();
53 security.checkCreateClassLoader ();
57 * Loads and link the class by the given name.
58 * @param name the name of the class.
59 * @return the class loaded.
60 * @see ClassLoader#loadClass(String,boolean)
61 * @exception java.lang.ClassNotFoundException
63 public Class loadClass(String name)
64 throws java.lang.ClassNotFoundException, java.lang.LinkageError
66 return loadClass (name, true);
70 * Loads the class by the given name.
71 * As per java 1.1, this has been deprecated. Use
72 * <code>loadClass(String)</code>
74 * @param name the name of the class.
75 * @param link if the class should be linked.
76 * @return the class loaded.
77 * @exception java.lang.ClassNotFoundException
80 protected abstract Class loadClass(String name, boolean link)
81 throws java.lang.ClassNotFoundException, java.lang.LinkageError;
84 * Defines a class, given the class-data. According to the JVM, this
85 * method should not be used; instead use the variant of this method
86 * in which the name of the class being defined is specified
89 * If the name of the class, as specified (implicitly) in the class
90 * data, denotes a class which has already been loaded by this class
91 * loader, an instance of
92 * <code>java.lang.ClassNotFoundException</code> will be thrown.
94 * @param data bytes in class file format.
95 * @param off offset to start interpreting data.
96 * @param len length of data in class file.
97 * @return the class defined.
98 * @exception java.lang.ClassNotFoundException
99 * @exception java.lang.LinkageError
100 * @see ClassLoader#defineClass(String,byte[],int,int) */
101 protected final Class defineClass(byte[] data, int off, int len)
102 throws java.lang.ClassNotFoundException, java.lang.LinkageError
104 return defineClass (null, data, off, len);
108 * Defines a class, given the class-data. This is preferable
109 * over <code>defineClass(byte[],off,len)</code> since it is more
110 * secure. If the expected name does not match that of the class
111 * file, <code>ClassNotFoundException</code> is thrown. If
112 * <code>name</code> denotes the name of an already loaded class, a
113 * <code>LinkageError</code> is thrown.
116 * FIXME: How do we assure that the class-file data is not being
117 * modified, simultaneously with the class loader running!? If this
118 * was done in some very clever way, it might break security.
119 * Right now I am thinking that defineclass should make sure never to
120 * read an element of this array more than once, and that that would
121 * assure the ``immutable'' appearance. It is still to be determined
122 * if this is in fact how defineClass operates.
124 * @param name the expected name.
125 * @param data bytes in class file format.
126 * @param off offset to start interpreting data.
127 * @param len length of data in class file.
128 * @return the class defined.
129 * @exception java.lang.ClassNotFoundException
130 * @exception java.lang.LinkageError
132 protected final synchronized Class defineClass(String name,
136 throws java.lang.ClassNotFoundException, java.lang.LinkageError
138 if (data==null || data.length < off+len || off<0 || len<0)
139 throw new ClassFormatError ("arguments to defineClass "
140 + "are meaningless");
143 if (name != null && findLoadedClass (name) != null)
144 throw new java.lang.LinkageError ("class "
146 + " already loaded");
149 // Since we're calling into native code here,
150 // we better make sure that any generated
151 // exception is to spec!
153 return defineClass0 (name, data, off, len);
155 } catch (java.lang.LinkageError x) {
158 } catch (java.lang.ClassNotFoundException x) {
161 } catch (java.lang.VirtualMachineError x) {
164 } catch (java.lang.Throwable x) {
165 // This should never happen, or we are beyond spec.
167 throw new InternalError ("Unexpected exception "
168 + "while defining class "
174 /** This is the entry point of defineClass into the native code */
175 private native Class defineClass0 (String name,
179 throws java.lang.ClassNotFoundException, java.lang.LinkageError;
182 /** This is called by defineClass0, once the "raw" and uninitialized
183 * class object has been created, and handles exceptions generated
184 * while actually defining the class (_Jv_DefineClass). defineClass0
185 * holds the lock on the new class object, so it needs to capture
186 * these exceptions. */
188 private static Throwable defineClass1 (Class klass, byte[] data,
189 int offset, int length)
192 defineClass2 (klass, data, offset, length);
193 } catch (Throwable x) {
199 /** This is just a wrapper for _Jv_DefineClass */
200 private static native void defineClass2 (Class klass, byte[] data,
201 int offset, int length)
205 * Link the given class. This will bring the class to a state where
206 * the class initializer can be run. Linking involves the following
209 * <LI> Prepare (allocate and internalize) the constant strings that
210 * are used in this class.
211 * <LI> Allocate storage for static fields, and define the layout
212 * of instance fields.
213 * <LI> Perform static initialization of ``static final'' int,
214 * long, float, double and String fields for which there is a
215 * compile-time constant initializer.
216 * <LI> Create the internal representation of the ``vtable''.
218 * For <code>gcj</code>-compiled classes, only the first step is
219 * performed. The compiler will have done the rest already.
221 * This is called by the system automatically,
222 * as part of class initialization; there is no reason to ever call
223 * this method directly.
225 * For historical reasons, this method has a name which is easily
226 * misunderstood. Java classes are never ``resolved''. Classes are
227 * linked; whereas method and field references are resolved.
229 * FIXME: The JDK documentation declares this method
230 * <code>final</code>, we declare it <code>static</code> -- any
231 * objections? This allows us to call it directly from native code
234 * @param clazz the class to link.
235 * @exception java.lang.LinkageError
237 protected static void resolveClass(Class clazz)
238 throws java.lang.LinkageError
244 } catch (Throwable x) {
245 markClassErrorState0 (clazz);
247 if (x instanceof Error)
250 throw new java.lang.InternalError
251 ("unexpected exception during linking: " + x);
256 /** Internal method. Calls _Jv_PrepareClass and
257 * _Jv_InternClassStrings. This is only called from resolveClass. */
258 private static native void linkClass0(Class clazz)
259 throws java.lang.LinkageError;
261 /** Internal method. Marks the given clazz to be in an erroneous
262 * state, and calls notifyAll() on the class object. This should only
263 * be called when the caller has the lock on the class object. */
264 private static native void markClassErrorState0(Class clazz);
268 * Returns a class found in a system-specific way, typically
269 * via the <code>java.class.path</code> system property.
271 * @param name the class to resolve.
272 * @return the class loaded.
273 * @exception java.lang.LinkageError
274 * @exception java.lang.ClassNotFoundException
276 protected native static Class findSystemClass(String name)
277 throws java.lang.ClassNotFoundException, java.lang.LinkageError;
280 * Does currently nothing.
282 protected final void setSigners(Class claz, Object[] signers) {
283 /* claz.setSigners (signers); */
287 * If a class named <code>name</code> was previously loaded using
288 * this <code>ClassLoader</code>, then it is returned. Otherwise
289 * it returns <code>null</code>.
290 * @param name class to find.
291 * @return the class loaded, or null.
293 protected native Class findLoadedClass(String name);
295 public static final InputStream getSystemResourceAsStream(String name) {
296 return system.getResourceAsStream (name);
299 public static final URL getSystemResource(String name) {
300 return system.getResource (name);
303 public static final byte[] getSystemResourceAsBytes(String name) {
304 return system.getResourceAsBytes (name);
308 * Return an InputStream representing the resource name.
309 * This is essentially like
310 * <code>getResource(name).openStream()</code>, except
311 * it masks out any IOException and returns null on failure.
312 * @param name resource to load
313 * @return an InputStream, or null
314 * @see java.lang.ClassLoader#getResource(String)
315 * @see java.lang.ClassLoader#getResourceAsBytes(String)
316 * @see java.io.InputStream
318 public InputStream getResourceAsStream(String name)
321 URL res = getResource (name);
322 if (res == null) return null;
323 return res.openStream ();
324 } catch (java.io.IOException x) {
330 * Return a byte array <code>byte[]</code> representing the
331 * resouce <code>name</code>. This only works for resources
332 * that have a known <code>content-length</code>, and
333 * it will block while loading the resource. Returns null
334 * for error conditions.<p>
335 * Since it is synchroneous, this is only convenient for
336 * resources that are "readily" available. System resources
337 * can conveniently be loaded this way, and the runtime
338 * system uses this to load class files. <p>
339 * To find the class data for a given class, use
340 * something like the following:
342 * String res = clazz.getName().replace ('.', '/')) + ".class";<br>
343 * byte[] data = getResourceAsBytes (res);
345 * @param name resource to load
346 * @return a byte array, or null
347 * @see java.lang.ClassLoader#getResource(String)
348 * @see java.lang.ClassLoader#getResourceAsStream(String)
350 public byte[] getResourceAsBytes(String name) {
352 URL res = getResource (name);
353 if (res == null) return null;
354 URLConnection conn = res.openConnection ();
355 int len = conn.getContentLength ();
356 if (len == -1) return null;
357 return readbytes (conn.getInputStream (), len);
358 } catch (java.io.IOException x) {
364 * Return an java.io.URL representing the resouce <code>name</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) {
376 * Utility routine to read a resource fully, even if the given
377 * InputStream only provides partial results.
379 private static byte[] readbytes (InputStream is, int length)
383 byte[] data = new byte[length];
387 while (off != length)
389 read = is.read (data, off, (int) (length-off));
398 } catch (java.io.IOException x) {