该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
自定义的classloader 不容易呀,,现在还有人研究这个,,我记得有一本书叫什么深入JAVa虚拟机的..挺深入的.
...
....
public class MyClassLoader extends ClassLoader {
private static String myClasspath = new String("");
private static Hashtable> loadClassHashTable = new Hashtable>();
private static Hashtable loadClassTime = new Hashtable();
public MyClassLoader() {
}
/** */
/**
* create a classloader and specify a classpath.
*
* @param myClasspath
* the specified classpath name.
*/
public MyClassLoader(String myClasspath) {
if (!myClasspath.endsWith("\\")) {
myClasspath = myClasspath + "\\";
}
MyClassLoader.myClasspath = myClasspath;
}
/** */
/**
* set the classpath
*
* @param myClasspath
* the specified classpath name
*/
public void SetmyClasspath(String myClasspath) {
if (!myClasspath.endsWith("\\")) {
myClasspath = myClasspath + "\\";
}
MyClassLoader.myClasspath = myClasspath;
}
/** */
/**
* Loads the class with the specified binary name. This method searches for
* classes in the same manner as the loadClass(String, boolean) method.
* Invoking this method is equivalent to invoking {loadClass(name,false)}.
*
* @param className
* The binary name of the class.
*
* @return The resulting Class object.
*
* @throws ClassNotFoundException
* If the class was not found.
*/
@SuppressWarnings("unchecked")
public Class loadClass(String className) throws ClassNotFoundException {
return loadClass(className, false);
}
/** */
/**
* Loads the class with the specified binary name. The default
* implementation of this method searches for classes in the following
* order:
*
* Invoke {findLoadedClass(String)} to check if the class has already been
* loaded.
*
* Invoke {findSystemClass(String)} to load the system class.
*
* Invoke the {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 {resolveClass(Class)} method on
* the resulting Class object.
*
* @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.
*/
@SuppressWarnings("unchecked")
protected Class loadClass(String name, boolean resolve)
throws ClassNotFoundException {
try {
Class foundClass = findLoadedClass(name);
// check if the class has already been loaded.
if (foundClass != null) {
System.out.println("Complete to load the class: " + name);
return foundClass;
}
// if the class is systemClass, load the system class by system
if (name.startsWith("java.")) {
foundClass = findSystemClass(name);
loadClassHashTable.put(name, foundClass);
System.out.println("System is loading the class: " + name);
return foundClass;
}
// invoke the findClass() method to load the class
try {
foundClass = findClass(name);
} catch (Exception fnfe) {
}
if (resolve && (foundClass != null)) {
resolveClass(foundClass);
}
return foundClass;
} catch (Exception e) {
throw new ClassNotFoundException(e.toString());
}
}
/** */
/**
* Finds the class with the specified binary name.The default implementation
* throws a ClassNotFoundException.
*
* @param className
* The binary name of the class.
*
* @return The resulting Class object.
*
* @throws ClassNotFoundException
* If the class could not be found.
*/
@SuppressWarnings("unchecked")
public Class findClass(String className) {
byte[] classData = null;
try {
classData = loadClassData(className);
} catch (IOException e) {
e.printStackTrace();
}
if (classData == null) {
return null;
}
System.out.println("MyClassLoader is loading : " + className + "");
Class c = defineClass(className, classData, 0, classData.length);
MyClassLoader.loadClassHashTable.put(className, c);
System.out.println("Complete to load the class :" + className);
return c;
}
/** */
/**
* Loads the classData with the specified binary name. This method searches
* for classes in the specified classpath as
* searchFile(myClasspath,className) method.
*
* @param className
* The binary name of the class
*
* @return The resulting the classData of the class object by byte[]
*
* @throws IOException
* if have some failed or interrupted I/O operations.
*/
private byte[] loadClassData(String className) throws IOException {
String filePath = searchFile(myClasspath, className + ".class");
if (!(filePath == null || filePath == "")) {
System.out.println("It have found the file : " + className
+ ". Begin to read the data and load the class。");
FileInputStream inFile = new FileInputStream(filePath);
byte[] classData = new byte[inFile.available()];
inFile.read(classData);
inFile.close();
loadClassTime.put(className, new File(filePath).lastModified());
return classData;
} else {
filePath = searchFile(myClasspath, className + ".java");
if (!(filePath == null || filePath == "")) {
System.out.println("It have found the file : " + filePath
+ ". Begin to translate");
Runtime.getRuntime().exec("javac " + filePath);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Translate it over : " + filePath);
return loadClassData(className);
} else {
System.out
.println("Haven't found the file, and fail to read the classData!");
return null;
}
}
}
/** */
/**
* Loads the class with the specified binary name.The default implementation
* throws a ClassNotFoundException.
*
* @param classData
* The data of the class.
* @param className
* The binary name of the class.
*
* @return The resulting Class object.
*
* @throws ClassNotFoundException
* If the class could not be found.
*/
public Class loadClass(byte[] classData, String className)
throws ClassNotFoundException {
System.out.println("MyClassLoader is loading : " + className + "");
Class c = defineClass(className, classData, 0, classData.length);
loadClassHashTable.put(className, c);
System.out.println("Complete to load the class :" + className);
return c;
}