Posted on 2007-04-13 20:59
久城 阅读(468)
评论(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仅用于个人学习交流!
目的在于记录个人成长.
所有文字均属于个人理解.
如有错误,望多多指教!不胜感激!