java 动态编译框架_利用 JDK6 动态编译组件搭建 OSGi 运行时编译环境

JDK6 动态编译组件

Java SE 6 之后自身集成了运行时编译的组件:javax.tools,存放在 tools.jar 包里,可以实现 Java 源代码编译,帮助扩展静态应用程序。该包中提供主要类可以从 Java String、StringBuffer 或其他 CharSequence 中获取源代码并进行编译。

接下来通过代码一步步讲述如何利用 JDK6 特性进行运行时编译。

清单 1. JDK6 动态编译代码片段

// 通过 ToolProvider 取得 JavaCompiler 对象,JavaCompiler 对象是动态编译工具的主要对象

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

// 通过 JavaCompiler 取得标准 StandardJavaFileManager 对象,StandardJavaFileManager 对象主要负责

// 编译文件对象的创建,编译的参数等等,我们只对它做些基本设置比如编译 CLASSPATH 等。

StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);

// 因为是从内存中读取 Java 源文件,所以需要创建我们的自己的 JavaFileObject,即 InMemoryJavaFileObject

JavaFileObject fileObject = new InMemoryJavaFileObject(className, codeString);

Iterable extends JavaFileObject> files = Arrays.asList(fileObject);

// 编译结果信息的记录

StringWriter sw = new StringWriter();

// 编译目的地设置

Iterable options = Arrays.asList("-d", classOutputFolder);

// 通过 JavaCompiler 对象取得编译 Task

JavaCompiler.CompilationTask task =

compiler.getTask(sw, fileManager, null, options, null, files);

// 调用 call 命令执行编译,如果不成功输出错误信息

if (!task.call()) {

String failedMsg = sw.toString();

System.out.println(“Build Error:” + failedMsg);

}

// 自定义 JavaFileObject 实现了 SimpleJavaFileObject,指定 string 为 java 源代码,这样就不用将源代码

// 存在内存中,直接从变量中读入即可。

public static class InMemoryJavaFileObject extends SimpleJavaFileObject {

private String contents = null;

public InMemoryJavaFileObject(String className, String contents) {

super(URI.create("string:///" + className.replace('.', '/') + Kind.SOURCE.extension),

Kind.SOURCE);

this.contents = contents;

}

public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {

return contents;

}

}

说明:注释详细说明了每一步的作用,通过 JDK 提供的 API,我们可以很简单也很灵活的进行动态运行时编译。

JRE 运行环境中如何进行动态编译

JRE 环境不像 JDK 环境,不带 javac 命令,也省略了 tools.jar 功能组件,所以自然也不具备运行时编译的功能。如果是这样读者可以用如下方式来解决这个问题:

找到 tools.jar,手动导入到 bundle 中并在 MANIFEST.MF 中添加依赖。

更改 JavaCompiler 的取得方式:

因为 ToolProvider.getSystemJavaCompiler() 还是通过运行时环境取得,JRE 环境下为 null,所以需要更改为直接从 Bundle-ClassPath 实例化:

JavaCompiler compiler = new com.sun.tools.javac.api.JavacTool();

这样就可以正常取得 JavaCompiler 进行运行时编译了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值