1、JDK6 动态编译组件

  Java SE 6 之后自身集成了运行时编译的组件:javax.tools,存放在 tools.jar 包里,可以实现 Java 源代码编译,帮助扩展静态应用程序。该包中提供主要类可以从 Java String、StringBuffer 或其他 CharSequence 中获取源代码并进行编译。接下来通过代码一步步讲述如何利用 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);

  // 从文件读取编译源代码
  //Files[] javafiles = ... ; // input for first compilation task
  //Iterable<? extends JavaFileObject> files = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(javafiles));

 // 编译结果信息的记录
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;
   }
}

http://www.ibm.com/developerworks/cn/java/j-lo-jdk6forosgi/

http://www.ibm.com/developerworks/cn/java/j-lo-jse64/index.html?S_TACT=105AGX52&S_CMP=techcto

http://docs.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html

http://dlc.sun.com.edgesuite.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html/zh_CN/api/javax/tools/JavaCompiler.html


Java 动态编译组件 & 类动态加载的更多相关文章

  1. java中带继承类的加载顺序详解及实战

    一.背景: 在面试中,在java基础方面,类的加载顺序经常被问及,很多时候我们是搞不清楚到底类的加载顺序是怎么样的,那么今天我们就来看看带有继承的类的加载顺序到底是怎么一回事?在此记下也方便以后复习巩 ...

  2. Java反射——java.lang.Class和类的加载

    反射的基础: java.lang.Class Class类的实例对象,用于记录类描述信息. 源码说:represent classes and interfaces in a running Java ...

  3. java类的加载、链接、初始化

    JVM和类的关系 当我们调用JAVA命令运行某个java程序时,该命令将会启动一条java虚拟机进程,不管该java程序有多么复杂,该程序启动了多少个线程,它们都处于该java虚拟机进程里.正如前面介 ...

  4. Java程序设计19——类的加载和反射-Part-A

    1 本文概要 本章介绍Java类的加载.连接和初始化的深入知识,并重点介绍Java反射相关的内容.本章知识偏底层点,这些运行原理有助于我们更好的把我java程序的运行.而且Java类加载器除了根加载器 ...

  5. java 类的加载、连接和初始化

    JVM和类 调用Java命令运行Java程序时,该命令将会启动一条Java虚拟机进程,不管该Java程序启动了多少条线程,创建了多少个变量,它们都处于该Java虚拟机进程里,共享该JVM进程的内存区. ...

  6. jvm(1)类的加载(三)(线程上下文加载器)

    简介: 类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的. Java Applet 需要从远程下载 Java 类文件到浏览器中并执行. 现在类加载器在 ...

  7. Java类的加载の动态

    类的加载方式 静态加载类,是编译时刻加载 动态加载类,是运行时刻加载 new创建对象:是静态加载类,在编译时刻就需要加载所有的可能使用到的类.有一个类有问题(如不存在),都不能通过编译,会报错. Cl ...

  8. 深入java虚拟机学习 -- 类的加载机制

    当看到"类的加载机制",肯定很多人都在想我平时也不接触啊,工作中无非就是写代码,不会了可以百度,至于类,jvm是怎么加载的我一点也不需要关心.在我刚开始工作的时候也觉得这些底层的内 ...

  9. 【转】怎么解决java.lang.NoClassDefFoundError错误 ,以及类的加载机制

    转自http://blog.csdn.net/jamesjxin/article/details/46606307 前言 在日常Java开发中,我们经常碰到java.lang.NoClassDefFo ...

随机推荐

  1. js常用方法收集

    JS获取地址栏制定参数值: //获取URL参数的值 function getUrlParam(name){ var reg = new RegExp("(^|&)"+ na ...

  2. 异常处理:Sys.WebForms.PageRequestManagerParserErrorException:The message……

    如果你为了使页面可以达到局部刷新的效果,并且用了UpdatePanel控件,这是如果你在后台页面用到Response对象时肯呢过会抛出一下异常: 解决方法:$(document).ready(func ...

  3. SVN并行开发管理策略

    总的原则:trunk保证相对稳定.分支合并到主干时将冲突降至最低. (1)       trunk用于集成.测试.发布,可以提交fixbug代码,但不允许直接提交新特性. (2)       特性在分 ...

  4. PHP注释有意思的排列

    <?php // // _ooOoo_ // o8888888o // 88" . "88 // (| -_- |) // O\ = /O // ____/`---'\___ ...

  5. 我的Android最佳实践之—— Android更新UI的两种方法:handler与runOnUiThread()

    在Android开发过程中,常需要更新界面的UI.而更新UI是要主线程来更新的,即UI线程更新.如果在主线线程之外的线程中直接更新页面 显示常会报错.抛出异常:android.view.ViewRoo ...

  6. 理解Socket编程【转载】

    “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket. ——有感于实际编程和开源项目研究. 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览 ...

  7. sql server中的左连接与右连接的简便写法

    左连接 *=(左表中的数据全部显示出来,右表中没有相关联的数据显示null) select Users.*,Department.name as DepartmentName from Users,D ...

  8. 不用配置tnsnames.ora,直接通过PL/SQL访问远程数据库

  9. Git-Flow

    Overview Git-Flow is a high-level command set wrapping low-level Git commands to support the "s ...

  10. BestCoder HDU 5750 Dertouzos

    Dertouzos 题意: 有中文,不说. 题解: 我看了别人的题解,还有个地方没懂, 为什么是 if(d%prime[i]==0) break; ? 代码: #include <bits/st ...