最近接触到公司一个项目,需要将生成的源码动态编译,记录下学习过程。

先贴出官网推荐写法:

JavaCompiler.CompilationTask getTask(Writer out,
                                     JavaFileManager fileManager,
                                     DiagnosticListener<? super JavaFileObject> diagnosticListener,
                                     Iterable<String> options,
                                     Iterable<String> classes,
                                     Iterable<? extends JavaFileObject> compilationUnits)

参数:out - 用于来自编译器的其他输出的 Writer;如果为 null,则使用 System.err

  fileManager - 文件管理器;如果为 null,则使用编译器的标准文件管理器 

    标准文件管理器有两个用途:

    • 自定义编译器如何读写文件的基本构建块

      •  在多个编译任务之间共享

  diagnosticListener - 诊断侦听器;如果为 null,则使用编译器的默认方法报告诊断信息

  options - 编译器选项; null 表示没有选项

  classes - 类名称(用于注释处理), null 表示没有类名称

  compilationUnits - 要编译的编译单元; null 表示没有编译单元

Files[] files1 = ...; // input for first compilation task
Files[] files2 = ...; // input for second compilation task

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

//DiagnosticCollector为诊断侦听器,用于将诊断信息收集在一个列表中

//可以不设置,为null时默认使用system.err

DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
//自定义编译器读写文件的基本构件块
Iterable<? extends JavaFileObject> compilationUnits1 = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(files1));
compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits1).call();

Iterable<? extends JavaFileObject> compilationUnits2 =  fileManager.getJavaFileObjects(files2); // use alternative method
// reuse the same file manager to allow caching of jar files
compiler.getTask(null, fileManager, null, null, null, compilationUnits2).call();

for (Diagnostic diagnostic :diagnostics.getDiagnostics())
System.out.format("Error on line %d in %d%n",
diagnostic.getLineNumber()
diagnostic.getSource().toUri());

fileManager.close();

记录下自己的一段代码:

public static void main(String[] args) {

//class文件生成目录
  String targetPath="D:\\generate\\target";

//源文件目录
  String sourcePath="D:\\generate\\source";
  File sourceFile=new File(sourcePath);
  List<File> sourceFiles = new ArrayList<File>();
  compiler(sourceFile,targetPath,sourceFiles);
  boolean result = compilerJavaFile(sourceFiles, targetPath);
  System.out.println("compiler finish!" + result);
 }

/**
  * 递归获取java文件
  * @param file 需要编译的文件夹
  * @param targetPath 编译后class类文件存放目录
  */
 public static void compiler(File file,String targetPath,List<File> sourceFiles) {
     File targetDir = new File(targetPath);
     if (! targetDir.exists())
     {
         targetDir.mkdirs();
     }
    if (file != null && file.exists()){
     File[] listFiles = file.listFiles();
     if (null == listFiles || listFiles.length == 0) {
        return;
     }
     for (File file2 : listFiles) {
        // 判断是否是文件夹
        if (file2.isDirectory()) {
             compiler(file2,targetPath,sourceFiles);
        } else {
           if (file2.getName().endsWith(".java")) {
           //将源文件目录中的Java文件加入集合中
             sourceFiles.add(file2);
         }
      }
    }
      }else{
        System.out.println("传入格式未知文件");
      }
 }

/**
  * 编译java文件
  * @param sourcePath
  * @param targerPath
  * @return
  */
 public static boolean compilerJavaFile(List<File> sourceFile, String targerPath) {

    StandardJavaFileManager fileManager = getJavaCompiler().getStandardFileManager(null, null, null);
    Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFile);
    return getJavaCompiler().getTask(null, fileManager, null, options, null, compilationUnits).call();

}

Java程序动态编译Java源文件的更多相关文章

  1. JAVA之动态编译

    通过Java动态生成class文件 今天说下JAVA中的动态编译,这个功能根据我现在的了解好像没有见到过用的,我Jio的吧,现在的一些在线代码编缉器可以用到了,这个具体我也不是很清楚.感兴趣的大家可以 ...

  2. 深入理解Java的动态编译

    前提 笔者很久之前就有个想法:参考现有的主流ORM框架的设计,造一个ORM轮子,在基本不改变使用体验的前提下把框架依赖的大量的反射设计去掉,这些反射API构筑的组件使用动态编译加载的实例去替代,从而可 ...

  3. DOS环境下含包并引用第三方jar的java程序的编译及运行

    DOS环境下含包并引用第三方jar的java程序的编译及运行 1.程序目录机构 bin:class文件生成目录 lib:第三方jar包目录 src:源程序文件目录 2.程序代码: 3.程序编译 jav ...

  4. Java初学者作业——编写 Java 程序,定义 Java 类 (Point) 用来表示坐标,坐标范围在(0,0)到(100,100)以内,并显示合法的坐标在控制台。

    返回本章节 返回作业目录 需求说明: 编写 Java 程序,定义 Java 类 Point 用来表示坐标,坐标范围在(0,0)到(100,100)以内,并显示合法的坐标在控制台. 实现思路: 定义 P ...

  5. IT兄弟连 Java语法教程 编译Java程序

    编写好Java程序的源代码后,接下来就应该编译该Java源文件来生成字节码文件了. 编译Java程序需要使用JDK中提供的javac命令,因为已经把javac命令所在的路径添加到了系统的Path环境变 ...

  6. [学习笔记]java基础Java8SE开发环境搭建、第一个Java Hello World、Java程序的编译与执行

    本文作者:sushengmiyan 本文地址:http://blog.csdn.net/sushengmiyan/article/details/25745945 内容简介: ------------ ...

  7. cmd命令对java程序进行编译时出现:编码GBK的不可映射字符

    原因:由于JDK是国际版的,在编译的时候,如果我们没有用-encoding参数指定JAVA源程序的编码格式,则java.exe首先获得我们才做系统默认采用的编码格式,也即在编译JAVA程序时,若我们不 ...

  8. Java的动态编译、动态加载、字节码操作

    想起来之前做的一个项目:那时候是把需要的源代码通过文件流输出到一个.java文件里,然后调用sun的Comipler接口动态编译成.class文件,然后再用专门写的一个class loader加载这个 ...

  9. (三)java程序的编译和执行

    编写java程序 eg class Demo { /* * 程序运行的入口 */ public static void main(String[] args) { System.out.println ...

随机推荐

  1. [egret+pomelo]实时游戏杂记(3)

    [egret+pomelo]学习笔记(1) [egret+pomelo]学习笔记(2) [egret+pomelo]学习笔记(3) 服务端的请求流程走完了一遍,下面就该看一下,在目前的服务端中,各服务 ...

  2. es6技巧写法

    为class绑定多个值 普通写法 :class="{a: true, b: true}" 其他 :class="['btn', 'btn2', {a: true, b: ...

  3. Object.create用法

    用法: Object.create(object, [,propertiesObject]) 创建一个新对象,继承object的属性,可添加propertiesObject添加属性,并对属性作出详细解 ...

  4. 6410开发板sd卡启动时烧写u-boot.bin以及u-boot-spl-16k.bin步骤

    参考文档:<SMDK6410_IROM_APPLICATION NOTE_REV 1.00>(可以从这里下载到> 参考博客:Tekkaman的博文<u-boot-2010.09 ...

  5. 按钮滚动到指定位置(JS)

    function intval(v) { v = parseInt(v); return isNaN(v) ? 0 : v; } function getPos(e) { var l = 0; var ...

  6. 分享知识-快乐自己:spring_Boot 中文返回给浏览器乱码 解析成问号?? fastJson jackJson

    心路历程: 在Controller中return 对象的时候,对象中的属性值中文部分在浏览器中 显示为问号?? 然后结果是这样的:?? 尝试排查原因: 中文乱码常有以下三种: 1.request.re ...

  7. 分享知识-快乐自己:Spring中的(三种)异常处理机制

    案例目录结构: Web.xml 配置: <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application ...

  8. Log4Net的使用之winform

    当我们将asp程序部署到远程服务器上的时候,如果遇到程序错误,如何能快速的判断我们程序的错误呢.所以-->Log4Net作为记录日志的一大神器,不得不学会熟练使用啊!没有那么多的原理,照猫画虎的 ...

  9. tensorboard 用法

    step1:  代码中把summary写到文件中 step2: dos窗口执行tensorboard命令 切换到代码所在目录下,输入: tensorboard --logdir=./tmp/graph ...

  10. Android 在Activity中对SQLite的操作

    注册 package com.scme.ui; import android.app.Activity; import android.content.Intent; import android.o ...