java compiler API实现java的动态编译

可以用JDK6 的Compiler API(JSR 199)去动态编译Java源文件,Compiler API结合反射功能就可以实现动态的产生Java代码并编译执行这些代码,有点动态语言的特征。 

Compiler API通过一套易用的标准的API提供了更加丰富的方式去做动态编译,而且是跨平台的。 

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public class CompilerDemo {

	public static void main(String[] args) {
		System.out.println(new File(".").getAbsolutePath());
		compiler1();
		compiler2();
	}

	/**
	 * 使用ToolProvider类来获得JavaCompiler接口的一个默认实现。
	 * ToolProvider类提供一个getSystemJavaCompiler()方法,返回JavaCompiler接口的一个实例
	 * 使用JavaCompiler最简单的方法是直接调用run()方法,run()方法是在Tool接口中实现的
	 */
	public static void compiler1() {
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		int results = compiler.run(null, null, null, "MBeanDemo1.java");
		System.out.println("Result code: " + results);
	}

	/**
	 * 这个方法利用了 StandardJavaFileManager类的优点。这个文件管理器提供了一种方法来完成普通文件的输入输出工作。 同时在一个
	 * DiagnosticListener实例的帮助下报告编译的诊断信息。后面将要用到的DiagnosticCollector类只是前面那个
	 * listener的一个实现。 在确定什么东西是需要编译的之前,你需要一个文件管理器。创建一个文件管理器需要两个基本的步骤:
	 * 创建一个DiagnosticCollector然后使用getStandardFileManager
	 * ()方法向JavaCompiler申请文件管理器。 传递
	 * DiagnosticListener实例作为getStandardFileManager()方法的参数。
	 * 这个listener报告非致命性的错误,你也可以选择通过将它传递给getTask()方法与编译器共享这个listener
	 */
	public static void compiler2() {
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
		StandardJavaFileManager fileManager = compiler.getStandardFileManager(
				diagnostics, null, null);
		Iterable<? extends JavaFileObject> compilationUnits = fileManager
				.getJavaFileObjectsFromStrings(Arrays.asList("MBeanDemo2.java","MBeanDemo3.java","MBeanDemo4.java"));
		JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager,
				diagnostics, null, null, compilationUnits);
		Boolean success = task.call();
		//输出编译出错的信息
		System.out.println( diagnostics.getDiagnostics().size());
		for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
			String str=String.format(
					"Code: %s%n" + "Kind: %s%n" + "Position: %s%n"
							+ "Start Position: %s%n" + "End Position: %s%n"
							+ "Source: %s%n" + "Message:   %s%n",
					diagnostic.getCode(), diagnostic.getKind(),
					diagnostic.getPosition(), diagnostic.getStartPosition(),
					diagnostic.getEndPosition(), diagnostic.getSource(),
					diagnostic.getMessage(null));
			System.out.println(str);
		}
		try {
			fileManager.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("Success: " + success);
	}

}

public class MBeanDemo1 {

	public static void main(String[] args) {
		System.out.println("MBeanDemo1");
	}
}

转自: http://blog.csdn.net/zhongweijian/article/details/7619396


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值