package com.compiler;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Locale;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class CompilerTest {
public static void main(String[] args) throws Exception {
String fileToCompile = "src" +File.separator + "com" + File.separator + "MoreErrors.java";//使用需要编译的class文件的路径来加载要编译的文件
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();//得到java底层提供的编译器
StandardJavaFileManager fileManager = compiler.getStandardFileManager(new MyDiagnosticListener(), null, null);//得到标准的java文件管理器
//
Iterable< ? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjectsFromStrings(Arrays.asList(fileToCompile));
Iterable< ? extends JavaFileObject> fileObjects = Arrays.asList(new StringSourceJavaObject());//生产java文件对象
CompilationTask task = compiler.getTask(null, fileManager, null, null, null, fileObjects);//通过java编译器得到需要编译的任务
boolean result = task.call();
if (result) {
//
Class cl = CompilerTest.class.getClassLoader().loadClass("com.MoreErrors");
System.out.println("编译成功。");
//
Object m = cl.newInstance();
//
Method method = cl.getMethod("errorTwo", new Class<?>[] {});
//
method.invoke(m, new Object[] {});
}
}
/**
* 这个类用于简化得到java字节码的内容可以让我们从任意地方得到需要编译的字节码内容
* @author Administrator
*
*/
static class StringSourceJavaObject extends SimpleJavaFileObject {
StringBuilder javaFileContents = new StringBuilder("" +
"class TestClass{" +
" public void testMethod(){" +
" System.out.println(" + "\"test\"" + ");" +
"}" +
"}");
public StringSourceJavaObject() throws URISyntaxException {
super(new URI("TestClass"), Kind.SOURCE);
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return javaFileContents.toString();
}
}
}
/**
* 在java字节文件编译过程中如果出现错误会自动地用该类报告错误
* @author YUTAO
*/
class MyDiagnosticListener implements DiagnosticListener{
public void report(Diagnostic diagnostic) {
System.out.println("Code->" + diagnostic.getCode());
System.out.println("Column Number->" + diagnostic.getColumnNumber());
System.out.println("End Position->" + diagnostic.getEndPosition());
System.out.println("Kind->" + diagnostic.getKind());
System.out.println("Line Number->" + diagnostic.getLineNumber());
System.out.println("Message->"+ diagnostic.getMessage(Locale.ENGLISH));
System.out.println("Position->" + diagnostic.getPosition());
System.out.println("Source" + diagnostic.getSource());
System.out.println("Start Position->" + diagnostic.getStartPosition());
System.out.println("\n");
}
}