Posted on 2007-04-13 20:59
久城 閱讀(470)
評論(0) 編輯 收藏 所屬分類:
JavaTest
研究JAVA CLASS LOADING已經好多天了。今天剛剛把代碼初步整理了下。等待導師的指點。
MyClassLoader.class文件。
自定義CLASSLOADER類的實現:

/** *//**
* classloader single
* @author zhaojiucheng,liji
* @version 1.2
* 在1.1的基礎上實現實現動態Reload
*/
package zhao;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;


/** *//**
* 自定義類加載器
*/

public class MyClassLoader extends ClassLoader
{

private static String MyClasspath = new String("");

private static ArrayList loadClassList = new ArrayList();

private static Hashtable loadClassHashTable = new Hashtable();

private static Hashtable loadClassTime = new Hashtable();


public MyClassLoader()
{

}


/** *//**
* 構造自定義的加載器 參數1:路徑名
*/

public MyClassLoader(String MyClasspath)
{

if (!MyClasspath.endsWith("\\"))
{
MyClasspath = MyClasspath + "\\";
}
this.MyClasspath = MyClasspath;
}


/** *//**
* 設置加載路徑 參數1:路徑名
*/

public void SetMyClasspath(String MyClasspath)
{

if (!MyClasspath.endsWith("\\"))
{
MyClasspath = MyClasspath + "\\";
}
this.MyClasspath = MyClasspath;
}


/** *//**
* 查找類并加載 參數1:文件名 被 loadClass() 調用
*/

public Class findClass(String name)
{
byte[] classData = null;

try
{
classData = loadClassData(name);

} catch (IOException e)
{
e.printStackTrace();
}
System.out.println("自定義加載器正在加載: " + name + "
");
Class c = defineClass(name, classData, 0, classData.length);
loadClassHashTable.put(name, c);
System.out.println("加載" + name + "類成功。");
return c;
}


/** *//**
* 讀取文件字節碼 參數1:文件名 被 findClass() 調用
*/

private byte[] loadClassData(String name) throws IOException
{
String filePath = searchFile(MyClasspath, name + ".class");

if (!(filePath == null || filePath == ""))
{
System.out.println("已經找到" + filePath + ",開始讀取字節碼并加載。");
FileInputStream inFile = new FileInputStream(filePath);
byte[] classData = new byte[inFile.available()];
inFile.read(classData);
inFile.close();
loadClassTime.put(name, new File(filePath).lastModified());
return classData;

} else
{
filePath = searchFile(MyClasspath, name + ".java");

if (!(filePath == null || filePath == ""))
{
System.out.println("已經找到" + filePath + "并開始編譯");
Runtime.getRuntime().exec("javac " + filePath);

try
{
Thread.sleep(1000);

} catch (InterruptedException e)
{
e.printStackTrace();
}
return loadClassData(name);

} else
{
System.out.println("未找到類文件,讀取字節碼失敗!");
return null;
}
}
}


/** *//**
* 加載類 參數1:字節碼數組 參數2:類名
*/
public Class loadClass(byte[] classData, String className)

throws ClassNotFoundException
{
System.out.println("自定義加載器正在加載: " + className + "
");
Class c = defineClass(className, classData, 0, classData.length);
loadClassHashTable.put(className, c);
System.out.println("加載" + className + "類成功。");
return c;
}


/** *//**
* 加載類 參數1:類名 類名從當前文件系統中查找指定的Class文件
*/

public Class loadClass(String name) throws ClassNotFoundException
{
return loadClass(name, false);
}


/** *//**
* 加載類 參數1:類名 參數2:是否分析這個類
*/
protected Class loadClass(String name, boolean resolve)

throws ClassNotFoundException
{
byte[] classData = null;
Class temp = null;

try
{
temp = findLoadedClass(name);

if (temp != null)
{
System.out.println(name + "類已被加載!");
return temp;
}
// 如是系統類直接裝載并記錄后返回

if (name.startsWith("java."))
{
temp = findSystemClass(name);
loadClassHashTable.put(name, temp);
System.out.println("系統正在加載 :" + name);
return temp;
}

try
{
temp = findClass(name);

} catch (Exception fnfe)
{
}

if (temp == null)
{
temp = findSystemClass(name);
}

if (resolve && (temp != null))
{
resolveClass(temp);
}
return temp;

} catch (Exception e)
{
throw new ClassNotFoundException(e.toString());
}
}


/** *//**
* 加載類 參數1:要加載的類名 參數2:類所在的jar包名
*/
protected Class loadClass(String className, String jarName)

throws ClassNotFoundException
{
String jarPath = searchFile(MyClasspath, jarName + ".jar");
JarInputStream in = null;

if (!(jarPath == null || jarPath == ""))
{

try
{
in = new JarInputStream(new FileInputStream(jarPath));
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.out.println("錯誤:無法讀取該文件!");
return null;
}
byte[] classData = new byte[(int) entry.getSize()];
System.out.println("已經找到" + className + ",開始讀取字節碼并加載。");
in.read(classData);
return loadClass(classData, className);
}
}
System.out.println("沒有找到 " + className + " 類文件");

} catch (IOException e)
{
e.printStackTrace();

} finally
{

try
{
in.close();

} catch (IOException e)
{
e.printStackTrace();
}
}

} else
{
System.out.println("沒有找到 " + jarName + ".jar");
return null;
}
return null;
}


/** *//**
* 參數1:要加載的類名 功能:實現動態Reload 不需要重新啟動虛擬機,把新添加的Class文件加載進入JVM,并且替換掉舊的Class文件
*/

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);
Class temp = null;

try
{
MyClassLoader mc2 = new MyClassLoader(MyClasspath);
mc2.loadClass(fileName);

} catch (ClassNotFoundException e)
{
e.printStackTrace();
}

} else
{
System.out.println("文件未更新。");
}
return null;
}


/** *//**
* 查詢文件 參數1:路徑名 參數2:文件名
*/

public String searchFile(String classpath, String fileName)
{
File f = new File(classpath + fileName);

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 + f.separator + objects[i])

.isDirectory())
{
String s = searchFile(classpath + objects[i] + f.separator,
fileName);

if (s == null || s == "")
{
continue;

} else
{
return s;
}
}
}
}
return null;
};


public static void main(String[] args)
{
MyClassLoader cl = new MyClassLoader();
cl.SetMyClasspath("d:\\soft");

try
{

while (true)
{
//System.out.println("load CTree:");
cl.loadClass("CTree");
cl.reload("CTree");

try
{
Thread.sleep(3000);

} catch (InterruptedException e)
{
e.printStackTrace();
}
}

} catch (Exception e)
{
e.printStackTrace();
}
}
}
MyThread.java文件。
實現線程監控。循環加載指定目錄下的類文件。
package zhao;

import java.io.File;
import java.util.Iterator;

import zhao.MyClassLoader;


public class MyThread extends Thread
{

private String filePath;

private MyClassLoader mcl;


public MyThread(String path)
{
this.filePath = path;
mcl = new MyClassLoader(path);
}


public void search(String filePath)
{
File dir = new File(filePath);
String[] fileList = dir.list();

for (int i = 0; i < fileList.length; i++)
{

if (new File(filePath + File.separator + fileList[i]).isDirectory())
{
search(filePath + fileList[i]);
} else if (new File(filePath + File.separator + fileList[i])

.isFile())
{


if (fileList[i].endsWith(".class"))
{

try
{
mcl.loadClass(fileList[i].substring(0, fileList[i]
.length() - 6));

} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
}
}


public void run()
{
int i = 1;

while (true)
{
search(filePath);
System.out.println("searching
" + i++ + "s");

try
{
Thread.sleep(1000);

} catch (InterruptedException e)
{
e.printStackTrace();
}

if (i == 20)
{
System.out.println("search over!");
break;
}
}
}


public static void main(String[] args)
{
MyThread t = new MyThread("D:\\soft\\aa");
t.start();
}
}

MyURLClassLoader.class文件。
繼承URLClassLoader類,實現加載網絡上的類。
package zhao;

import java.net.*;


public class MyURLClassLoader extends URLClassLoader
{


public MyURLClassLoader(URL[] url)
{
super(url);
}


public Class findClass(final String name)
{

try
{
return super.findClass(name);

} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
return null;
}


public static void main(String[] args)
{
URL url = null;

try
{
url = new URL("http://192.168.44.19:8088/WebTest/");

} catch (MalformedURLException e)
{
e.printStackTrace();
}
MyURLClassLoader urlClassLoader1 = new MyURLClassLoader(

new URL[]
{ url });
Class c1 = urlClassLoader1.findClass("Tree");
System.out.println(c1);

}

}

歡迎來訪!^.^!
本BLOG僅用于個人學習交流!
目的在于記錄個人成長.
所有文字均屬于個人理解.
如有錯誤,望多多指教!不勝感激!