1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| public class ClassCompiler {
//JavaFileObject接口实现类,用于JavaCompiler编译源码 static class StrJavaFileObject extends SimpleJavaFileObject {
final String code; protected StrJavaFileObject(String name, String code) { //Kind枚举类位于JavaFileObject接口,Kind.SOURCE.extension是java文件的后缀(".java") super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE); this.code = code; } @Override //SimpleJavaFileObject未实现该方法,FileObject获取内容用 public CharSequence getCharContent(boolean ignoreEncodingErrors) { return code; } } //使用当前线程的资源绝对路径 public static String getDefaultOutPath(){ String outDir = ""; try { File classPath = new File(Thread.currentThread().getContextClassLoader() .getResource("").toURI()); outDir = classPath.getAbsolutePath() + File.separator; } catch (URISyntaxException e1) { e1.printStackTrace(); } return outDir; } //编译Java文件,filePath是文件路径 public boolean compileJavaFile(String filePath){ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); Iterable<String> options = Arrays.asList("-d", getDefaultOutPath()); Iterable<? extends JavaFileObject> compilationUnits = compiler .getStandardFileManager(null, null, null) .getJavaFileObjectsFromFiles(Arrays.asList(new File( filePath))); return compiler.getTask(null, null, null, options, null, compilationUnits).call(); } // 将JavaCompiler.getTask搬过来 // CompilationTask getTask(Writer out, //additional output // JavaFileManager fileManager,//null使用编译器标准文件管理器 // DiagnosticListener<? super JavaFileObject> diagnosticListener,//诊断监听器,null时使用默认方法报告诊断信息 // Iterable<String> options,//编译参数,null时没有编译参数 // Iterable<String> classes,//待编译类名,可为null // Iterable<? extends JavaFileObject> compilationUnits);//待编译的代码 // getTask创建了一个编译任务,task.call()执行该编译任务 //编译类 //className是类名(无需带包名),javaCodes是该类的代码 public boolean compile(String className, String javaCodes) { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StrJavaFileObject srcObject = new StrJavaFileObject(className, javaCodes); Iterable<? extends JavaFileObject> fileObjects = Arrays.asList(srcObject); Iterable<String> options = Arrays.asList("-d", getDefaultOutPath());
return compiler.getTask(null, null, null, options, null, fileObjects).call(); } public static void main(String[] args){ String classPath = ClassCompiler.getDefaultOutPath(); String javaFilePath = "****\\Test.java"; String code = "package lyyljs.hotclassloader;" + "public class Test implements Printer {" + "public boolean print() {" + "System.out.println(\"Test1 Out\");" + "return true;" + "}}"; ClassCompiler cc = new ClassCompiler(); //一个ClassLoader不能重复加载某个class HotClassLoader clsLoader1 = new HotClassLoader(classPath); HotClassLoader clsLoader2 = new HotClassLoader(classPath); boolean result = cc.compileJavaFile(javaFilePath); if (!result){ System.out.println("compile Test failed!"); return; } Class clazz = clsLoader1.findClass("lyyljs.hotclassloader.Test"); try { Printer p1 = (Printer) clazz.newInstance(); p1.print(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } result = cc.compile("Test", code); clazz = clsLoader2.findClass("lyyljs.hotclassloader.Test"); try { Printer p2 = (Printer) clazz.newInstance(); p2.print(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }
|