博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java_java动态编译整个项目,解决jar包找不到问题
阅读量:6815 次
发布时间:2019-06-26

本文共 11501 字,大约阅读时间需要 38 分钟。

java动态编译整个项目,解决jar包找不到问题

原文:http://itzyx.com/index.php/javac/

动态将java文件编译为class文件解决方案:

将temp\sdl\src目录中的java源文件编译成class文件,并存放到temp\sdl\classes目录中

java中早就提供了用java方式去动态编译java源文件的接口,有关java动态编译的API都在javax.tools包中。使用jdk1.6以上版本提供的JavaCompiler工具来动态编译java源文件。

我们可以通过ToolProvider类的静态方法getSystemJavaCompiler得到JavaCompiler对象实例。
// 获取编译器实例
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

得到JavaCompiler对象实例后,我们可以调用该工具的getTask(Writer out, JavaFileManager fileManager, DiagnosticListener<? super JavaFileObject> diagnosticListener, Iterable<String> options, Iterable<String> classes, Iterable<? extends JavaFileObject> compilationUnits) 方法获取一个编译任务对象。

CompilationTask compilationTask = compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits);

该方法的第一个参数为文件输出,这里我们可以不指定,我们采用javac命令的-d参数来指定class文件的生成目录。

第二个参数为文件管理器实例

// 获取标准文件管理器实例 StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);

 

该文件管理器实例的作用就是将我们需要动态编译的java源文件转换为getTask需要的编译单元。

// 获取要编译的编译单元 Iterable
compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFileList);

 

第三个参数DiagnosticCollector<JavaFileObject> diagnostics是在编译出错时,存放编译错误信息。

第四个参数为编译命令选项,就是javac命令的可选项,这里我们主要使用了-d和-sourcepath这两个选项。

/** * 编译选项,在编译java文件时,编译程序会自动的去寻找java文件引用的其他的java源文件或者class。 -sourcepath选项就是定义java源文件的查找目录, -classpath选项就是定义class文件的查找目录,-d就是编译文件的输出目录。 */ Iterable
options =Arrays.asList("-encoding",encoding,"-classpath",jars,"-d", targetDir, "-sourcepath", sourceDir);

 

第五个参数为类名称

第六个参数为上面提到的编译单元,就是我们需要编译的java源文件
当我们得到CompilationTask compilationTask编译任务后,我们就可以调用compilationTask.call()方法进行编译工作

// 运行编译任务 compilationTask.call()

 

 

package com.lkb.autoCode.util;import javax.tools.*;import javax.tools.JavaCompiler.CompilationTask;import java.io.File;import java.io.FileFilter;import java.io.IOException;import java.util.ArrayList;import java.util.Arrays;import java.util.List;public class DynamicCompilerUtil {    private String jars = "";    private String targetDir = "";    /**     * 判断字符串是否为空 有值为true 空为:false     */    public boolean isnull(String str) {        if (null == str) {            return false;        } else if ("".equals(str)) {            return false;        } else if (str.equals("null")) {            return false;        } else {            return true;        }    }    /**     * 编译java文件     *     * @param encoding    编译编码     * @param jars        需要加载的jar     * @param filePath    文件或者目录(若为目录,自动递归编译)     * @param sourceDir   java源文件存放目录     * @param targetDir   编译后class类文件存放目录     * @param diagnostics 存放编译过程中的错误信息     * @return     * @throws Exception     */    public boolean compiler(String encoding, String jars, String filePath, String sourceDir, String targetDir, DiagnosticCollector
diagnostics) throws Exception { // 获取编译器实例 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); // 获取标准文件管理器实例 StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); try { if (!isnull(filePath) && !isnull(sourceDir) && !isnull(targetDir)) { return false; } // 得到filePath目录下的所有java源文件 File sourceFile = new File(filePath); List
sourceFileList = new ArrayList
(); this.targetDir = targetDir; getSourceFiles(sourceFile, sourceFileList); // 没有java文件,直接返回 if (sourceFileList.size() == 0) { System.out.println(filePath + "目录下查找不到任何java文件"); return false; } // 获取要编译的编译单元 Iterable
compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFileList); /** * 编译选项,在编译java文件时,编译程序会自动的去寻找java文件引用的其他的java源文件或者class。 -sourcepath选项就是定义java源文件的查找目录, -classpath选项就是定义class文件的查找目录。 */ Iterable
options = Arrays.asList("-encoding", encoding, "-classpath", jars, "-d", targetDir, "-sourcepath", sourceDir); CompilationTask compilationTask = compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits); // 运行编译任务 return compilationTask.call(); } finally { fileManager.close(); } } /** * 查找该目录下的所有的java文件 * * @param sourceFile * @param sourceFileList * @throws Exception */ private void getSourceFiles(File sourceFile, List
sourceFileList) throws Exception { if (sourceFile.exists() && sourceFileList != null) {
//文件或者目录必须存在 if (sourceFile.isDirectory()) {
// 若file对象为目录 // 得到该目录下以.java结尾的文件或者目录 File[] childrenFiles = sourceFile.listFiles(new FileFilter() { public boolean accept(File pathname) { if (pathname.isDirectory()) { try { new CopyDirectory().copyDirectiory(pathname.getPath(), targetDir + pathname.getPath().substring(pathname.getPath().indexOf("src") + 3, pathname.getPath().length())); } catch (IOException e) { e.printStackTrace(); } return true; } else { String name = pathname.getName(); if (name.endsWith(".java") ? true : false) { return true; } try { new CopyDirectory().copyFile(pathname, new File(targetDir + pathname.getPath().substring(pathname.getPath().indexOf("src") + 3, pathname.getPath().length()))); } catch (IOException e) { e.printStackTrace(); } return false; } } }); // 递归调用 for (File childFile : childrenFiles) { getSourceFiles(childFile, sourceFileList); } } else {
// 若file对象为文件 sourceFileList.add(sourceFile); } } } /** * 查找该目录下的所有的jar文件 * * @param jarPath * @throws Exception */ private String getJarFiles(String jarPath) throws Exception { File sourceFile = new File(jarPath); // String jars=""; if (sourceFile.exists()) {
// 文件或者目录必须存在 if (sourceFile.isDirectory()) {
// 若file对象为目录 // 得到该目录下以.java结尾的文件或者目录 File[] childrenFiles = sourceFile.listFiles(new FileFilter() { public boolean accept(File pathname) { if (pathname.isDirectory()) { return true; } else { String name = pathname.getName(); if (name.endsWith(".jar") ? true : false) { jars = jars + pathname.getPath() + ";"; return true; } return false; } } }); } } return jars; } public static void main(String[] args) { try { // 编译F:\\亚信工作\\SDL文件\\sdl\\src目录下的所有java文件 String filePath = "E:\\workspace\\COD-MS\\src"; String sourceDir = "E:\\workspace\\COD-MS\\src"; String jarPath = "E:\\workspace\\COD-MS\\WebRoot\\WEB-INF\\lib"; String targetDir = "E:\\java\\project\\bin"; DiagnosticCollector
diagnostics = new DiagnosticCollector
(); DynamicCompilerUtil dynamicCompilerUtil = new DynamicCompilerUtil(); boolean compilerResult = dynamicCompilerUtil.compiler("UTF-8", dynamicCompilerUtil.getJarFiles(jarPath), filePath, sourceDir, targetDir, diagnostics); if (compilerResult) { System.out.println("编译成功"); } else { System.out.println("编译失败"); for (Diagnostic diagnostic : diagnostics.getDiagnostics()) { // System.out.format("%s[line %d column %d]-->%s%n", diagnostic.getKind(), diagnostic.getLineNumber(), // diagnostic.getColumnNumber(), // diagnostic.getMessage(null)); System.out.println(diagnostic.getMessage(null)); } } } catch (Exception e) { e.printStackTrace(); } }}

 

package com.lkb.autoCode.util;import java.io.*;/** * 复制文件夹或文件夹 */public class CopyDirectory {    // 源文件夹    String url1 = "E:\\workspace\\DeployeTest";    // 目标文件夹    String url2 = "E:\\java\\project\\bin";    public static void main(String args[]) throws IOException {        CopyDirectory copyDirectory = new CopyDirectory();        // 创建目标文件夹        (new File(copyDirectory.url2)).mkdirs();        // 获取源文件夹当前下的文件或目录        File[] file = (new File(copyDirectory.url1)).listFiles();        for (int i = 0; i < file.length; i++) {            if (file[i].isFile()) {                // 复制文件                copyDirectory.copyFile(file[i], new File(copyDirectory.url2 + file[i].getName()));            }            if (file[i].isDirectory()) {                // 复制目录                String sourceDir = copyDirectory.url1 + File.separator + file[i].getName();                String targetDir = copyDirectory.url2 + File.separator + file[i].getName();                copyDirectory.copyDirectiory(sourceDir, targetDir);            }        }    }    /**     * 复制文件     *     * @param sourceFile 源文件     * @param targetFile 目标文件     * @throws IOException     */    public void copyFile(File sourceFile, File targetFile)            throws IOException {        // 新建文件输入流并对它进行缓冲        FileInputStream input = new FileInputStream(sourceFile);        BufferedInputStream inBuff = new BufferedInputStream(input);        // 新建文件输出流并对它进行缓冲        FileOutputStream output = new FileOutputStream(targetFile);        BufferedOutputStream outBuff = new BufferedOutputStream(output);        // 缓冲数组        byte[] b = new byte[1024 * 5];        int len;        while ((len = inBuff.read(b)) != -1) {            outBuff.write(b, 0, len);        }        // 刷新此缓冲的输出流        outBuff.flush();        // 关闭流        inBuff.close();        outBuff.close();        output.close();        input.close();    }    /**     * 复制文件夹     *     * @param sourceDir 源文件夹路径     * @param targetDir 目标文件夹路径     * @throws IOException     */    public void copyDirectiory(String sourceDir, String targetDir)            throws IOException {        // 新建目标目录        (new File(targetDir)).mkdirs();        // 获取源文件夹当前下的文件或目录        File[] file = (new File(sourceDir)).listFiles();        for (int i = 0; i < file.length; i++) {            if (file[i].isFile()) {                // 源文件                File sourceFile = file[i];                // 目标文件                File targetFile = new File(new File(targetDir)                        .getAbsolutePath()                        + File.separator + file[i].getName());                copyFile(sourceFile, targetFile);            }            if (file[i].isDirectory()) {                // 准备复制的源文件夹                String dir1 = sourceDir + "/" + file[i].getName();                // 准备复制的目标文件夹                String dir2 = targetDir + "/" + file[i].getName();                copyDirectiory(dir1, dir2);            }        }    }}

 

摘自百度文库:http://wenku.baidu.com/link?url=hFsuio_UxS4_vkt7ov8grKZp40rxJ8AR_ktzhNReoG4MGXFKf-dP_wVodVsErD737eKvaaNhVY9yEBdyXG1IEgiZeukpGU93pxCBTIbXvq3###

 

转载地址:http://xudzl.baihongyu.com/

你可能感兴趣的文章
枚举 POJ 1753 Flip Game
查看>>
洛谷3396:哈希冲突——题解
查看>>
Mysql之数据库设计
查看>>
Java Enum
查看>>
method="post" 用户名和密码不显示在网址里
查看>>
LeetCode----8. String to Integer (atoi)(Java)
查看>>
JSP标签
查看>>
Python--day65--母版和继承的基本使用
查看>>
在python 3.6的eclipse中,导入from lxml import etree老是提示,Unresolved import:etree的错误...
查看>>
经纬度计算距离
查看>>
Linux 在添加一个新账号后却没有权限怎么办
查看>>
React 源码剖析系列 - 不可思议的 react diff
查看>>
走近抽象类与抽象方法
查看>>
4. 寻找两个有序数组的中位数
查看>>
React组件开发总结
查看>>
各种符号
查看>>
大道至简,职场上做人做事做管理
查看>>
抗干扰的秘诀:分类、整理与专注
查看>>
Number of Connected Components in an Undirected Graph
查看>>
BZOJ 3143 游走(高斯消元)
查看>>