private static String myClasspath = new String(""); public static Hashtable<String, Class<?>> loadClassHashTable = new Hashtable<String, Class<?>>(); private static Hashtable<String, Long> loadClassTime = new Hashtable<String, Long>();
public MyClassLoader() {
}
public static String getMyClasspath() { return myClasspath; } public static void setMyClasspath(String myClasspath) { MyClassLoader.myClasspath = myClasspath; } public static Hashtable<String, Class<?>> getLoadClassHashTable() { return loadClassHashTable; } public static void setLoadClassHashTable( Hashtable<String, Class<?>> loadClassHashTable) { MyClassLoader.loadClassHashTable = loadClassHashTable; } public static Hashtable<String, Long> getLoadClassTime() { return loadClassTime; } public static void setLoadClassTime(Hashtable<String, Long> loadClassTime) { MyClassLoader.loadClassTime = loadClassTime; } /** */ /** * 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 <tt>Class</tt> 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) { }
/** */ /** * 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) {
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 name * 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 {
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; }
/** */ /** * Loads the class with the specified binary name.The default implementation * throws a ClassNotFoundException. * * @param className * The binary name of the class. * @param jarName * The binary name of the jar that search the class from it. * * @return The resulting Class object. * * @throws ClassNotFoundException * If the class could not be found. */ public Class loadClass(String className, String jarName) throws ClassNotFoundException {
try { in = new JarInputStream(new FileInputStream(jarPath)); System.out.println(22222222); JarEntry entry; while ((entry = in.getNextJarEntry()) != null) { String outFileName = entry.getName().substring( entry.getName().lastIndexOf("/") + 1, entry.getName().length()); if (outFileName.equals(className + ".class")) { if (entry.getSize() == -1) { System.err.println("error : can't read the file!"); return null; } byte[] classData = new byte[(int) entry.getSize()]; System.out .println("It have found the file : " + className + ". Begin to read the data and load the class。"); in.read(classData); return loadClass(classData, className); } } System.out.println("Haven't found the file " + className + " in " + jarName + ".jar."); } catch (IOException e) { e.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } else { System.out.println("Haven't found the jarFile: " + jarName + ".jar."); return null; } return null; }
/** */ /** * Reloads the class with the specified binary name. Needn't have to restart * JVM then reload the class. * * @param className * The binary name of the class need to reload . * * @return The resulting Class object. * * @throws ClassNotFoundException * If the class was not found. */ public Class reload(String fileName) {
String filePath = searchFile(myClasspath, fileName + ".class"); Long a = new File(filePath).lastModified();
if (!a.equals(loadClassTime.get(fileName))) { loadClassHashTable.remove(fileName); loadClassTime.remove(fileName); try { MyClassLoader mc2 = new MyClassLoader(myClasspath); mc2.loadClass(fileName); } catch (ClassNotFoundException e) { e.printStackTrace(); } } else { System.out .println("The class is the newest version , needn't reloading."); } return null; }
/** */ /** * search the file with the specified binary name. Needn't have to restart * JVM then reload the class. * * @param classpath * the specified path where we search. * @param fileName * The binary name of the file that want to search. * * @return The resulting file path. */ public String searchFile(String classpath, String fileName) {
try {
FileInputStream fi2 = new FileInputStream(new File( "E:/zdes/Aone.class"));
byte encryptedData[] = new byte[fi2.available()];
fi2.read(encryptedData);
fi2.close();
MyClassLoader mcl = new MyClassLoader();
Class cl = mcl.loadClass(encryptedData, "Aone");
Method mainMethod = cl.getMethod("testAone");
mainMethod.invoke(cl, null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
package util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Hashtable;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
public class MyClassLoader extends ClassLoader {
private static String myClasspath = new String("");
public static Hashtable<String, Class<?>> loadClassHashTable = new Hashtable<String, Class<?>>();
private static Hashtable<String, Long> loadClassTime = new Hashtable<String, Long>();
public MyClassLoader() {
}
public static String getMyClasspath() {
return myClasspath;
} public static void setMyClasspath(String myClasspath) {
MyClassLoader.myClasspath = myClasspath;
} public static Hashtable<String, Class<?>> getLoadClassHashTable() {
return loadClassHashTable;
} public static void setLoadClassHashTable(
Hashtable<String, Class<?>> loadClassHashTable) {
MyClassLoader.loadClassHashTable = loadClassHashTable;
} public static Hashtable<String, Long> getLoadClassTime() {
return loadClassTime;
} public static void setLoadClassTime(Hashtable<String, Long> loadClassTime) {
MyClassLoader.loadClassTime = loadClassTime;
} /** */
/**
* 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 <tt>Class</tt> 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 name
* 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;
}
/** */
/**
* Loads the class with the specified binary name.The default implementation
* throws a ClassNotFoundException.
*
* @param className
* The binary name of the class.
* @param jarName
* The binary name of the jar that search the class from it.
*
* @return The resulting Class object.
*
* @throws ClassNotFoundException
* If the class could not be found.
*/
public Class loadClass(String className, String jarName)
throws ClassNotFoundException {
String jarPath = searchFile(myClasspath, jarName + ".jar");
System.out.println(jarPath);
JarInputStream in = null;
System.out.println(111111111);
if (!(jarPath == null || jarPath == "")) {
try {
in = new JarInputStream(new FileInputStream(jarPath));
System.out.println(22222222);
JarEntry entry;
while ((entry = in.getNextJarEntry()) != null) {
String outFileName = entry.getName().substring(
entry.getName().lastIndexOf("/") + 1,
entry.getName().length());
if (outFileName.equals(className + ".class")) {
if (entry.getSize() == -1) {
System.err.println("error : can't read the file!");
return null;
}
byte[] classData = new byte[(int) entry.getSize()];
System.out
.println("It have found the file : "
+ className
+ ". Begin to read the data and load the class。");
in.read(classData);
return loadClass(classData, className);
}
}
System.out.println("Haven't found the file " + className
+ " in " + jarName + ".jar.");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
System.out.println("Haven't found the jarFile: " + jarName
+ ".jar.");
return null;
}
return null;
}
/** */
/**
* Reloads the class with the specified binary name. Needn't have to restart
* JVM then reload the class.
*
* @param className
* The binary name of the class need to reload .
*
* @return The resulting Class object.
*
* @throws ClassNotFoundException
* If the class was not found.
*/
public Class reload(String fileName) {
String filePath = searchFile(myClasspath, fileName + ".class");
Long a = new File(filePath).lastModified();
if (!a.equals(loadClassTime.get(fileName))) {
loadClassHashTable.remove(fileName);
loadClassTime.remove(fileName);
try {
MyClassLoader mc2 = new MyClassLoader(myClasspath);
mc2.loadClass(fileName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} else {
System.out
.println("The class is the newest version , needn't reloading.");
}
return null;
}
/** */
/**
* search the file with the specified binary name. Needn't have to restart
* JVM then reload the class.
*
* @param classpath
* the specified path where we search.
* @param fileName
* The binary name of the file that want to search.
*
* @return The resulting file path.
*/
public String searchFile(String classpath, String fileName) {
String cut = fileName.substring(fileName.lastIndexOf('.'), fileName
.length());
String path = fileName.substring(0, fileName.lastIndexOf('.')).replace(
'.', '/')
+ cut;
File f = new File(classpath + path);
if (f.isFile()) {
return f.getPath();
} else {
String objects[] = new File(classpath).list();
for (int i = 0; i < objects.length; i++) {
if (new File(classpath + File.separator + objects[i])
.isDirectory()) {
String s = searchFile(classpath + objects[i]
+ File.separator, fileName);
if (s == null || s == "") {
continue;
} else {
return s;
}
}
}
}
return null;
};
}