vmsystemclassloader.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 695 行 · 第 1/2 页
JAVA
695 行
/**
* $Id: VmSystemClassLoader.java,v 1.5 2004/02/20 08:21:02 epr Exp $
*
* Copyright 2001-2003, E.W. Prangsma
*
* All rights reserved
*/
package org.jnode.vm;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.jnode.assembler.ObjectResolver;
import org.jnode.vm.classmgr.ClassDecoder;
import org.jnode.vm.classmgr.SelectorMap;
import org.jnode.vm.classmgr.VmMethod;
import org.jnode.vm.classmgr.VmStatics;
import org.jnode.vm.classmgr.VmType;
import org.jnode.vm.compiler.NativeCodeCompiler;
/**
* Default classloader.
*
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
public final class VmSystemClassLoader extends VmAbstractClassLoader {
private transient TreeMap classInfos;
private VmType[] bootClasses;
private transient URL classesURL;
private transient boolean verbose = false;
private transient boolean failOnNewLoad = false;
private transient ClassLoader classLoader;
private transient ObjectResolver resolver;
private byte[] systemRtJar;
private static JarFile systemJarFile;
private final ClassLoader parent;
/** Our mapping from method signatures to selectors */
private final SelectorMap selectorMap;
private final VmArchitecture arch;
private boolean requiresCompile = false;
private final VmStatics statics;
/**
* Constructor for VmClassLoader.
*
* @param classesURL
* @param arch
*/
public VmSystemClassLoader(URL classesURL, VmArchitecture arch) {
this(classesURL, arch, null);
}
/**
* Constructor for VmClassLoader.
*
* @param classesURL
* @param arch
*/
public VmSystemClassLoader(URL classesURL, VmArchitecture arch,
ObjectResolver resolver) {
this.classesURL = classesURL;
this.classInfos = new TreeMap();
this.parent = null;
this.selectorMap = new SelectorMap();
this.arch = arch;
this.resolver = resolver;
this.statics = new VmStatics(arch, resolver);
}
/**
* Constructor for VmClassLoader.
*
* @param classLoader
*/
public VmSystemClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
this.classInfos = new TreeMap();
this.parent = classLoader.getParent();
final VmSystemClassLoader sysCl = VmSystem.getSystemClassLoader();
this.selectorMap = sysCl.selectorMap;
this.arch = sysCl.arch;
this.statics = sysCl.statics;
}
/**
* Gets the collection with all currently loaded classes. All collection
* elements are instanceof VmClass.
*
* @return Collection
*/
public Collection getLoadedClasses() {
if (classInfos != null) {
final ArrayList list = new ArrayList();
for (Iterator i = classInfos.values().iterator(); i.hasNext();) {
final ClassInfo ci = (ClassInfo) i.next();
if (ci.isLoaded()) {
try {
list.add(ci.getVmClass());
} catch (ClassNotFoundException ex) {
/* ignore */
}
}
}
return list;
} else {
final ArrayList list = new ArrayList();
final VmType[] arr = bootClasses;
final int count = arr.length;
for (int i = 0; i < count; i++) {
list.add(arr[ i]);
}
return list;
}
}
/**
* Gets the number of loaded classes.
*/
public int getLoadedClassCount() {
if (classInfos != null) {
return classInfos.size();
} else {
return bootClasses.length;
}
}
/**
* Gets the loaded class with a given name, or null if no such class has
* been loaded.
*
* @param name
* @return VmClass
*/
public VmType findLoadedClass(String name) {
if (classInfos != null) {
if (name.indexOf('/') >= 0) { throw new IllegalArgumentException(
"name contains '/'"); }
final ClassInfo ci = getClassInfo(name, false);
if (ci != null) {
try {
return ci.getVmClass();
} catch (ClassNotFoundException ex) {
throw new RuntimeException(ex);
}
} else {
return null;
}
} else {
final VmType[] list = bootClasses;
final int count = list.length;
for (int i = 0; i < count; i++) {
VmType vmClass = list[ i];
if (vmClass.nameEquals(name)) { return vmClass; }
}
return null;
}
}
/**
* Result all loaded classes as an array of VmClass entries.
*
* @return VmClass[]
* @throws ClassNotFoundException
*/
public VmType[] prepareAfterBootstrap() throws ClassNotFoundException {
if (this.classInfos != null) {
final VmType[] result = new VmType[ classInfos.size()];
int j = 0;
for (Iterator i = classInfos.values().iterator(); i.hasNext();) {
final ClassInfo ci = (ClassInfo) i.next();
result[ j++] = ci.getVmClass();
}
bootClasses = result;
return result;
} else {
return bootClasses;
}
}
/**
* Add a class that has been loaded.
*
* @param name
* @param cls
*/
public synchronized void addLoadedClass(String name, VmType cls) {
if (failOnNewLoad) { throw new RuntimeException(
"Cannot load a new class when failOnNewLoad is set (" + name
+ ")"); }
if (classInfos != null) {
classInfos.put(name, new ClassInfo(cls));
}
}
/**
* Gets the ClassInfo for the given name. If not found and create is True,
* a new ClassInfo is created, added to the list and returned. If not found
* and create is False, null is returned.
*
* @param name
* @param create
* @return
*/
private synchronized ClassInfo getClassInfo(String name, boolean create) {
ClassInfo ci = (ClassInfo) classInfos.get(name);
if (ci != null) {
return ci;
} else if (create) {
ci = new ClassInfo(name);
classInfos.put(name, ci);
}
return ci;
}
/**
* Load a class with a given name
*
* @param name
* @param resolve
* @see org.jnode.vm.classmgr.VmClassLoader#loadClass(String, boolean)
* @return The loaded class
* @throws ClassNotFoundException
*/
public VmType loadClass(String name, boolean resolve)
throws ClassNotFoundException {
// Also implement the java.lang.ClassLoader principals here
// otherwise they cannot work in java.lang.ClassLoader.
if ((parent != null) && !parent.skipParentLoader(name)) {
try {
final Class cls = parent.loadClass(name);
return cls.getVmClass();
} catch (ClassNotFoundException ex) {
// Don't care, try it ourselves.
}
}
VmType cls = findLoadedClass(name);
if (cls != null) { return cls; }
if (classInfos == null) {
//Unsafe.debug("classInfos==null");
throw new ClassNotFoundException(name); }
//BootLog.debug("load class" + name);
if (name.indexOf('/') >= 0) { throw new IllegalArgumentException(
"name contains '/'"); }
final ClassInfo ci = getClassInfo(name, true);
if (!ci.isLoaded()) {
try {
if (failOnNewLoad) { throw new RuntimeException(
"Cannot load a new class when failOnNewLoad is set ("
+ name + ")"); }
if (name.charAt(0) == '[') {
ci.setVmClass(loadArrayClass(name, resolve));
} else {
ci.setVmClass(loadNormalClass(name));
}
} catch (ClassNotFoundException ex) {
ci.setLoadError(ex.toString());
classInfos.remove(ci.getName());
throw new ClassNotFoundException(name, ex);
} catch (IOException ex) {
ci.setLoadError(ex.toString());
classInfos.remove(ci.getName());
throw new ClassNotFoundException(name, ex);
}
if (resolve) {
ci.getVmClass().link();
}
}
return ci.getVmClass();
}
/**
* Gets the ClassLoader belonging to this loader.
*
* @return ClassLoader
*/
public final ClassLoader asClassLoader() {
if (classLoader == null) {
classLoader = new ClassLoaderWrapper(this);
}
return classLoader;
}
/**
* Load a normal (non-array) class with a given name
*
* @param name
* @return VmClass
* @throws IOException
* @throws ClassNotFoundException
*/
private VmType loadNormalClass(String name) throws IOException,
ClassNotFoundException {
if (failOnNewLoad) { throw new RuntimeException(
"Cannot load a new class when failOnNewLoad is set (" + name
+ ")"); }
boolean rejectNatives = (!name.equals("org.jnode.vm.Unsafe"));
//System.out.println("bvi.loadClass: " +name);
byte[] image = getClassStream(name);
return ClassDecoder.defineClass(name, image, 0, image.length,
rejectNatives, this);
}
/**
* Gets the number of loaded classes.
*
* @return int
*/
public int size() {
if (classInfos != null) {
return classInfos.size();
} else {
return bootClasses.length;
}
}
/**
* Gets an inputstream for the class file that contains the given
* classname.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?