package com.easyooo.framework.rule.java; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.tools.DiagnosticCollector; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.easyooo.framework.rule.RuleException; import com.easyooo.framework.rule.impl.AbstractRuleClassLoader; import com.easyooo.framework.rule.impl.ScriptWriter; /** * Java动态编译 * * @author Killer */ public class JavaRuleClassLoader extends AbstractRuleClassLoader { protected final Logger logger = LoggerFactory.getLogger(getClass()); private String classpath; private final List<String> OPTIONS; public JavaRuleClassLoader() { initClassPath(); OPTIONS = new ArrayList<String>(); OPTIONS.add("-encoding"); OPTIONS.add("UTF-8"); OPTIONS.add("-classpath"); OPTIONS.add(classpath); } private void initClassPath() { // get parent classLoader URLClassLoader parentClassLoader = (URLClassLoader) this.getClass() .getClassLoader(); // classpath from parent class loader StringBuilder sb = new StringBuilder(); for (URL url : parentClassLoader.getURLs()) { String p = url.getFile(); sb.append(p).append(File.pathSeparator); } this.classpath = sb.toString(); } @Override public Class<?> loadClass(File sourceFile, ScriptWriter sw) throws RuleException { StandardJavaFileManager sjfm = null; try{ JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); sjfm = javaCompiler.getStandardFileManager(null, null, null); Iterable<? extends JavaFileObject> it = sjfm.getJavaFileObjects(sourceFile); // Fault diagnosis device DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<JavaFileObject>(); // create compliation task CompilationTask task = javaCompiler.getTask(null, sjfm, dc, OPTIONS, null, it); // start compliation boolean success = task.call(); if(success){ return sw.getScriptClass(); }else{ this.printError(dc); throw new CompileException(dc); } }catch(NullPointerException e){ throw new RuleException("Do not support the compilation, Please try to for JDK jre replacement" , e); }catch(Throwable e){ throw new RuleException("Compile the Java file error" , e); }finally{ try { sjfm.close(); } catch (IOException e) { logger.error("Compile the Java source file, unable " + "to shut StandardJavaFileManager", e); } } } private void printError(DiagnosticCollector<JavaFileObject> dc){ for (Iterator<?> ite = dc.getDiagnostics().iterator(); ite.hasNext(); ) { logger.error(ite.next().toString()); } } }