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


    java动态编译整个项目,解决jar包找不到问题
    原文:http://itzyx.com/index.php/javac/

    动态将java文件编译为class文件解决方案:
    将tempsdlsrc目录中的java源文件编译成class文件,并存放到tempsdlclasses目录中

    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<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFileList);

    第三个参数DiagnosticCollector<JavaFileObject> diagnostics是在编译出错时,存放编译错误信息。
    第四个参数为编译命令选项,就是javac命令的可选项,这里我们主要使用了-d和-sourcepath这两个选项。

    /** 
    * 编译选项,在编译java文件时,编译程序会自动的去寻找java文件引用的其他的java源文件或者class。 -sourcepath选项就是定义java源文件的查找目录, -classpath选项就是定义class文件的查找目录,-d就是编译文件的输出目录。 
    */ 
    Iterable<String> 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<JavaFileObject> 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<File> sourceFileList = new ArrayList<File>();
                this.targetDir = targetDir;
                getSourceFiles(sourceFile, sourceFileList);
                // 没有java文件,直接返回
                if (sourceFileList.size() == 0) {
                    System.out.println(filePath + "目录下查找不到任何java文件");
                    return false;
                }
                // 获取要编译的编译单元
                Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFileList);
                /**
                 * 编译选项,在编译java文件时,编译程序会自动的去寻找java文件引用的其他的java源文件或者class。 -sourcepath选项就是定义java源文件的查找目录, -classpath选项就是定义class文件的查找目录。
                 */
                Iterable<String> 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<File> 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<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
                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###

  • 相关阅读:
    java基础(七)面向对象(二)
    java基础 (六)面向对象(一)
    java基础(五)
    java基础(四)
    sqlloader导出数据和导入数据
    SQL LOADER 的用法 TXT文件导入非常之快
    在线代码对比/匹配 代码对比 在线文本比较
    JAVA 调用命令并输出
    RFC总结-SD模块
    使用BAPI_ACC_DOCUMENT_POST,创建会计凭证,用BADI扩展字段(转)
  • 原文地址:https://www.cnblogs.com/gisblogs/p/5508664.html
Copyright © 2020-2023  润新知