Milán Major

netscape-revival

1 branch
Code

sun-java/classsrc/java/lang/ClassLoader.java

/*
 * @(#)ClassLoader.java	1.30 96/03/27 Arthur van Hoff
 *
 * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and without
 * fee is hereby granted provided that this copyright notice
 * appears in all copies. Please refer to the file "copyright.html"
 * for further important copyright and licensing information.
 *
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */

package java.lang;

import java.io.InputStream;
import java.lang.SecurityManager;

/**
 * ClassLoader is an abstract Class that can be used to define a policy
 * for loading Java classes into the runtime environment. By default,
 * the runtime system loads classes that originate as files by reading 
 * them from the directory defined by the <tt>CLASSPATH</tt> environment
 * variable (this is platform dependent). The default mechanism does not involve
 * a Class loader. <p>
 *
 * However, some classes may not originate from a file; they could be
 * loaded from some other source, e.g., the network. Classes loaded
 * from the network are an array of bytes. A ClassLoader can be used to
 * tell the runtime system to convert an array of bytes into an instance
 * of class Class.
 * This conversion information is passed to the runtime using the defineClass()
 * method.<p>
 *
 * Classes that are created through the defineClass() mechanism can 
 * reference other classes by name. To resolve those names, the runtime
 * system calls the ClassLoader that originally created the Class.
 * The runtime system calls the abstract method loadClass() to load
 * the referenced classes.<p>
 * <pre>
 * 	ClassLoader loader = new NetworkClassLoader(host, port);
 *  	Object main = loader.loadClass("Main").newInstance();
 *	....
 * </pre>
 *
 * The NetworkClassLoader subclass must define the method loadClass() to 
 * load a Class from the network. Once it has downloaded the bytes
 * that make up the Class it should use the method defineClass() to create a Class
 * instance. A sample implementation could be:
 * <pre>
 *	class NetworkClassLoader {
 *	    String host;
 *	    int port;
 *	    Hashtable cache = new Hashtable();
 *
 *	    private byte loadClassData(String name)[] {
 *		// load the class data from the connection
 *		...
 *	    }
 *
 *	    public synchronized Class loadClass(String name) {
 *	        Class c = cache.get(name);
 *		if (c == null) {
 *		    byte data[] = loadClassData(name);
 *		    cache.put(name, defineClass(name, data, 0, data.length));
 *		}
 *		return c;
 *	    }
 *	}
 * </pre>
 * @see		Class
 * @version 	1.30, 27 Mar 1996
 * @author	Arthur van Hoff
 */

public abstract class ClassLoader {

    /**
     * If initialization succeed this is set to true and security checks will
     * succeed. Otherwise the object is not initialized and the object is
     * useless.
     */
    private boolean initialized = false;

    /**
     * Constructs a new Class loader and initializes it.
     */
    protected ClassLoader() {
	SecurityManager.checksCreateClassLoader(1);
	init();
	initialized = true;
    }

    /**
     * Resolves the specified name to a Class. The method loadClass() is 
     * called by the virtual machine.
     * As an abstract method, loadClass() must be defined in a subclass of 
     * ClassLoader. By using a Hashtable, you can avoid loading the same 
     * Class more than once. 
     * @param	name	the name of the desired Class
     * @param resolve true if the Class needs to be resolved
     * @return		the resulting Class, or null if it was not found.
     * @exception ClassNotFoundException 
     *                         Cannot find a definition for the class
     * @see		java.util.Hashtable
     */
    protected abstract Class loadClass(String name, boolean resolve) throws ClassNotFoundException;

    /**
     * Converts an array of bytes to an instance of class Class. Before the
     * Class can be used it must be resolved.
     * @param	data	the bytes that make up the Class
     * @param	offset	the start offset of the Class data
     * @param	length	the length of the Class data
     * @return		the Class object which was created from the data.
     * @exception ClassFormatError If the data does not contain a valid 
     * Class.
     * @see 		ClassLoader#loadClass
     * @see 		ClassLoader#resolveClass
     * This method is deprecated in favor of the version that takes a "name"
     * as a first argument, and is *MUCH* more secure.
     */
    protected final Class defineClass(byte data[], int offset, int length) {
        return defineClass(null, data, offset, length);
    }

    /**
     * Converts an array of bytes to an instance of a named class Class. Before the
     * Class can be used it must be resolved.
     * @param	name	the expected name of the class; null if unknown; using '.' and not '/' as separator
     * @param	data	the bytes that make up the Class
     * @param	offset	the start offset of the Class data
     * @param	length	the length of the Class data
     * @return		the Class object which was created from the data.
     * @exception ClassFormatError If the data does not contain a valid 
     * Class.
     * @see 		ClassLoader#loadClass
     * @see 		ClassLoader#resolveClass
     */
    protected native final Class defineClass(String name, byte data[], int offset, int length);

    /**
     * Resolves classes referenced by this Class. This must be done before the
     * Class can be used. Class names referenced by the resulting Class are
     * resolved by calling loadClass().
     * @param	c	the Class to be resolved
     * @see 		ClassLoader#defineClass
     */
    protected native final void resolveClass(Class c);

    /**
     * Loads a system Class. A system Class is a class with the
     * primordial Class loader (which is null).
     * @param name the name of the system Class
     * @exception NoClassDefFoundError If the Class is not found.
     * @exception ClassNotFoundException 
     *                         Cannot find a definition for the class
     */
    protected native final Class findSystemClass(String name) throws ClassNotFoundException;

    /**
     * Initializes the Class loader.
     */
    private native void init();


    /* Throw an exception if this class is not properly initialized.
     * This method is used predominantly in the C code (directly)
     */
    private native void checkInitialized();
}