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

先贴出官网推荐写法:

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. linux内核中创建线程方法【转】

    本文转载自:https://www.cnblogs.com/Ph-one/p/6077787.html 1.头文件 #include <linux/sched.h> //wake_up_p ...

  2. 分享知识-快乐自己:SpringMvc中的四种数据源及相关配置(整合快速集成开发)

     数据库连接: jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://39.105.105.186:3306/SpringMybatis?us ...

  3. struts2 validate手动验证

    我们前面学习struts2知道,struts2通过拦截器实现了一些验证操作. 比如,如果是不能转换的类型在action中接受的话会跳转到错误页面,错误信息中会包含对应的错误信息,例如: 首先我们了解一 ...

  4. LinkedList_1.打印两个有序链表的公共部分

    思路: 实例化出两个链表($link_a, $link_b),比较连个链表当前元素的大小,谁小谁执行next()方法继续比较,当出现相当的时候把相等的值塞入数组$common里,当两个链表有一个元素比 ...

  5. str_1.判断两个字符串每个字符出现的次数一样

    1.两个字符串每个字符出现的次数一样 $str1 = "ab'c4*"; $str2 = "cb*'a4"; $ret = isBX($str1, $str2) ...

  6. 小程序写tab和swiper切换结合效果

    实现代码如下: wxml页面 <scroll-view scroll-x="true" class="weui-navbar"> <block ...

  7. ivew组件的使用

    iview的官网:https://www.iviewui.com/docs/guide/start 1.选择快速上手 2.安装 解压,cmd,cd进你解压后的文件,cnpm i 3.打包 npm ru ...

  8. poj 2559 最大矩形面积(单调栈)

    题目:输入一个整数n,代表有n个  1(宽度) * h[i](高度)的矩形.接下来n个数依次给定一个矩形高度的高度h[i](i<=n). 求:在给定的依次排列的这堆矩形构成的图形里用一个矩形圈出 ...

  9. 基于zookeeper的MySQL主主负载均衡的简单实现

    1.先上原理图 2.说明 两个mysql采用主主同步的方式进行部署. 在安装mysql的服务器上安装客户端(目前是这么做,以后想在zookeeper扩展集成),客户端实时监控mysql应用的可用性,可 ...

  10. 14 vue学习 postcssrc eslintrc.js babelrc

    一  .postcssrc.js 众所周知为兼容所有浏览器,有的CSS属性需要对不同的浏览器加上前缀,然而有时添加一条属性,需要添加3~4条类似的属性只是为了满足浏览器的兼容,这不仅会增加许多的工作量 ...