java 自制類加載器的簡單實現

jopen 11年前發布 | 13K 次閱讀 Java Java開發

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;

public class CompileClassLoader extends ClassLoader{

//讀取一個文件的內容 private byte[] getBytes(String filename)throws IOException{ File file = new File(filename); long len = file.length(); byte[] raw = new byte[(int)len]; try( FileInputStream fin = new FileInputStream(file); ){ //一次讀取Class文件的全部二進制數據 int r = fin.read(raw); if(r != len){ throw new IOException("無法讀取全部文件:"+r+" != "+len); }

return raw; } }

private boolean compile(String javaFile) throws IOException{ System.out.println("CompileClassLoader:正在編譯 "+javaFile+"..."); //調用系統的javac命令 Process p = Runtime.getRuntime().exec("javac "+javaFile); try{ p.waitFor(); }catch (InterruptedException e) { System.out.println(e); } //獲取javac線程的退出值 int ret = p.exitValue(); return ret == 0; }

protected Class<?> findClass(String name) throws ClassNotFoundException{ Class clazz = null; //將包路徑中的點(.)替換成斜線(/) String fileStub = name.replace(".", "/"); String javaFilename = fileStub + ".java"; String classFilename = fileStub + ".class"; File javaFile = new File(javaFilename); File classFile = new File(classFilename); //當指定的java源文件存在,且class文件不存在,或者Java源文件的修改時間比class文件的修改時間更晚時,重新編譯 if(javaFile.exists()&&(!classFile.exists()||javaFile.lastModified()>classFile.lastModified())){ try{ //如果編譯失敗,或者改class文件不存在 if(!compile(javaFilename)||!classFile.exists()){ throw new ClassNotFoundException("ClassNotFoundException:"+javaFilename); } }catch (IOException e) { e.printStackTrace(); } } //如果class文件存在,系統負責將該文件轉換成class對象 if(classFile.exists()){ try{ //將class文件的二進制數據讀入數組 byte[] raw = getBytes(classFilename); //調用classloader的defineclass方法將二進制數據轉換成class對象 clazz = defineClass(name, raw, 0, raw.length); }catch(IOException e){ e.printStackTrace(); } } if(clazz==null){ throw new ClassNotFoundException(name); } return clazz; }

public static void main(String[] args) throws Exception { //如果運行該程序時沒有參數,既沒有目標類 if(args.length<1){ System.out.println("缺少目標類,請按如下格式運行java源文件:"); System.out.println("java CompileClassLoader ClassName"); } //第一個參數是需要運行的類 String progClass = args[0]; //剩下的參數將作為運行目標類的參數 //將這些參數復制到一個新數組中 String[] progArgs = new String[args.length-1]; System.arraycopy(args, 1, progArgs, 0, progArgs.length); CompileClassLoader cc1 = new CompileClassLoader(); //加載需要運行的類 Class<?> clazz = cc1.loadClass(progClass); //獲取需要運行的類的主要方法 Method main = clazz.getMethod("main",(new String[0]).getClass()); Object argsArray[] = {progArgs}; main.invoke(null, argsArray); }

} </pre>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!