簡述
該類使用javax.tools.ToolProvider自帶的JavaCompiler進行編譯,使用IO的File及NIO的Files進行對應的路徑創建、讀取及拷貝,使用正則表達式進行包名與目錄的轉換,我只是將這些東西做了個容錯整合,沒什麼技術含量,就為個方便吧。
模塊API
class DynamicReactor://空參構造public Class<?> dynamicCompile(String srcPath);//輸入一個指定的源文件路徑,若編譯、拷貝成功則返回該類對應的Class類實例private String changePacketToDic(String packageName);//將一個合法的包名轉換為對應JavaClassPath中的路徑(我是用的是eclipse 所以需要對應地增加bin這一目錄,若使用其他不同編譯器,請參考對應的運行上下文設置進行適當修改) private String getPackage(String srcPath);//由一個合法的java文件路徑嘗試獲得其包名
原始碼
import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.io.IOException;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.nio.file.StandardCopyOption;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.tools.JavaCompiler;import javax.tools.ToolProvider;/** * DynamicReactor 一個動態編譯模塊,負責編譯源文件,複製到對應包下及加載類等過程(JDK 1.7) * @author 三向板磚* */public class DynamicReactor {JavaCompiler compiler;Pattern packagePattern;static final String regEx = "(?<=package//s).*(?=;)";public DynamicReactor() {compiler = ToolProvider.getSystemJavaCompiler();packagePattern = Pattern.compile(regEx);}/** * 動態編譯給定源文件* @param srcPath 源文件路徑* @return Class * <br>若成功返回對應類的Class實例* <br>若失敗返回null * */public Class<?> dynamicCompile(String srcPath) {Class<?> result = null;//獲得給定路徑源文件的String packName = getPackage(srcPath);if(packName == null) {System.out.println("DynamicRector:Load packageName Error!");return null;}//調用compiler編譯指定源文件int res = compiler.run(null, null, null,srcPath);if(res != 0) {System.out.println("DynamicRector:Compile Java Source Error!");return null;}//獲得包名對應的路徑,若路徑不存在則創建,若指定class文件存在則覆蓋String packageDst = changePacketToDic(packName);File dstDir = new File(packageDst);if(!dstDir.exists()) {dstDir.mkdirs();}Path pathFrom = Paths.get(srcPath.split("//.java")[0] + ".class");Path pathTo = Paths.get(packageDst,pathFrom.getFileName().toString());try {Files.move(pathFrom, pathTo, StandardCopyOption.REPLACE_EXISTING);}catch (IOException e) {System.out.println("DynamicRector:Move File Fail!");e.printStackTrace();}try {result = Class.forName(packName+"."+pathFrom.getFileName().toString().split("//.class")[0]);}catch (ClassNotFoundException e) {System.out.println("DynamicRector:Class Not found in Final!");}return result;}//該方法將一個合法包名轉化為對應路徑private String changePacketToDic(String packageName) {String[] dirs = packageName.split("//.");String res = ".//bin";for (int i = 0;i < dirs.length;i++) {res += "//"+dirs[i];}return res;}//該方法從給定的路徑源文件中獲得包名private String getPackage(String srcPath) {String result = null;BufferedReader br;try {br = new BufferedReader(new FileReader(srcPath));String data = br.readLine();while(data != null) {if(data.indexOf("package") != -1) {Matcher m = packagePattern.matcher(data);if(m.find()) {result = m.group();}break;}data = br.readLine();}br.close();}catch (IOException e) {System.out.println("DynamicRector:Error in open file "+srcPath);}return result;}}總結
以上就是本文關於java編程進行動態編譯加載代碼分享的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!