java.lang.ClassLoader Maven / Gradle / Ivy
package java.lang;
import java.io.InputStream;
import java.net.URL;
import java.util.Objects;
/**
* This stripped down ClassLoader class is simply here to give us cross-platform support for code
* that might need a valid classloader.
*
*
* xapi-gwt-reflect does call into the one and only system classloader, to define mappings of
* java-names to runtime classes, in order to enable Class.forName() and ClassLoader.loadClass();
*
*
* @author "James X. Nelson ([email protected])"
*
*/
public class ClassLoader {
// The parent class loader for delegation
private final ClassLoader parent;
/**
* Creates a new class loader using the specified parent class loader for delegation.
*
* @param parent The parent class loader
*/
protected ClassLoader(final ClassLoader parent) {
this.parent = parent;
}
/**
* Creates a new class loader using the ClassLoader returned by the method
* {@link #getSystemClassLoader() getSystemClassLoader()} as the parent class loader.
*/
protected ClassLoader() {
this(getSystemClassLoader());
}
// -- Class --
/**
* Loads the class with the specified binary name. This method searches for
* classes in the same manner as the {@link #loadClass(String, boolean)} method. It is invoked by
* the Java virtual machine to resolve class references. Invoking this method is equivalent to
* invoking {@link #loadClass(String, boolean) loadClass(name,
* false)}.
*
*
* @param name The binary name of the class
*
* @return The resulting Class object
*
* @throws ClassNotFoundException If the class was not found
*/
public Class> loadClass(final String name) throws ClassNotFoundException {
return this.loadClass(name, false);
}
/**
* Loads the class with the specified binary name. The default implementation
* of this method searches for classes in the following order:
*
*
* -
*
* Invoke {@link #findLoadedClass(String)} to check if the class has already been loaded.
*
*
*
* -
*
* Invoke the {@link #loadClass(String) loadClass} method on the parent class loader. If
* the parent is null the class loader built-in to the virtual machine is used, instead.
*
*
*
* -
*
* Invoke the {@link #findClass(String)} method to find the class.
*
*
*
*
*
*
* If the class was found using the above steps, and the resolve flag is true, this
* method will then invoke the {@link #resolveClass(Class)} method on the resulting Class
* object.
*
*
*
* Subclasses of ClassLoader are encouraged to override {@link #findClass(String)},
* rather than this method.
*
*
* @param name The binary name of the class
*
* @param resolve If true then resolve the class
*
* @return The resulting Class object
*
* @throws ClassNotFoundException If the class could not be found
*/
protected Class> loadClass(final String name, final boolean resolve)
throws ClassNotFoundException {
// First, check if the class has already been loaded
Class> clazz = null; // TODO: reimplement this goodness findLoadedClass(name);
if (clazz == null) {
try {
if (parent == null) { // NOPMD
// clazz = findBootstrapClassOrNull(name);
} else {
clazz = parent.loadClass(name, false);
}
} catch (final ClassNotFoundException e) { // NOPMD
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (clazz == null) {
// If still not found, then invoke findClass in order
// to find the class.
clazz = findClass(name);
}
}
// if (resolve) {
// resolveClass(c);
// }
return clazz;
}
// This method is invoked by the virtual machine to load a class.
private Class> loadClassInternal(final String name) // NOPMD
throws ClassNotFoundException {
return this.loadClass(name);
}
/**
* Finds the class with the specified binary name. This method should be
* overridden by class loader implementations that follow the delegation model for loading
* classes, and will be invoked by the {@link #loadClass loadClass} method after checking
* the parent class loader for the requested class. The default implementation throws a
* ClassNotFoundException.
*
*
* @param name The binary name of the class
*
* @return The resulting Class object
*
* @throws ClassNotFoundException If the class could not be found
*
* @since 1.2
*/
protected Class> findClass(final String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
}
/**
* Finds a class with the specified binary name, loading it if necessary.
*
*
* This method loads the class through the system class loader (see
* {@link #getSystemClassLoader()}). The Class object returned might have more than one
* ClassLoader associated with it. Subclasses of ClassLoader need not usually
* invoke this method, because most class loaders need to override just
* {@link #findClass(String)}.
*
*
* @param name The binary name of the class
*
* @return The Class object for the specified name
*
* @throws ClassNotFoundException If the class could not be found
*
* @see #ClassLoader(ClassLoader)
* @see #getParent()
*/
protected final Class> findSystemClass(final String name) throws ClassNotFoundException {
return getSystemClassLoader().loadClass(name);
}
/**
* No-op for compatibility.
*/
protected final void setSigners(final Class> pclass, final Object[] signers) {
// do nothing
}
// -- Resource --
public URL getResource(final String name) {
// TODO return a magic url backed by an IO request
return null;
}
/**
* Unsupported.
*/
public InputStream getResourceAsStream(final String name) {
throw new UnsupportedOperationException();
// URL url = getResource(name);
// try {
// return url != null ? url.openStream() : null;
// } catch (IOException e) {
// return null;
// }
}
/**
* Unsupported.
*/
public static InputStream getSystemResourceAsStream(final String name) {
throw new UnsupportedOperationException();
// URL url = getSystemResource(name);
// try {
// return url != null ? url.openStream() : null;
// } catch (IOException e) {
// return null;
// }
}
/**
* Returns the parent class loader for delegation. Some implementations may use null to
* represent the bootstrap class loader. This method will return null in such
* implementations if this class loader's parent is the bootstrap class loader.
*
*/
public final ClassLoader getParent() {
return parent;
}
private static ClassLoader cl;
/**
* get system class loader.
*
* @return ClassLoader
*/
public static ClassLoader getSystemClassLoader() {
if (cl == null) { // NOPMD
cl = new ClassLoader(null);
}
return cl;
}
// Returns true if the specified class loader can be found in this class
// loader's delegation chain.
@SuppressWarnings("checkstyle:rightCurly")
boolean isAncestor(final ClassLoader cl) {
ClassLoader acl = this;
do {
acl = acl.parent;
if (Objects.equals(cl, acl)) {
return true;
}
} while (acl != null);
return false;
}
// Returns the invoker's class loader, or null if none.
// NOTE: This must always be invoked when there is exactly one intervening
// frame from the core libraries on the stack between this method's
// invocation and the desired invoker.
static ClassLoader getCallerClassLoader() {
return getSystemClassLoader();
}
// Invoked in the java.lang.Runtime class to implement load and loadLibrary.
static void loadLibrary(final Class> fromClass, final String name, final boolean isAbsolute) {}
}