将Java文件编译成Jar包

1.将指定目录下的java文件编译为class文件

import org.apache.commons.lang3.StringUtils;
import javax.tools.*;
import java.io.File;
import java.util.Arrays;
import java.util.List;

// 将java文件编译为class文件
public class CompilerUtil {
    private static JavaCompiler javaCompiler = null;

    private static String UTF = "UTF-8";

    private CompilerUtil(){

    }

    private static JavaCompiler getJavaCompiler(){
        if (javaCompiler == null) {
            synchronized (CompilerUtil.class){
                if (javaCompiler == null) {
                    javaCompiler = ToolProvider.getSystemJavaCompiler();
                }
            }
        }
        return javaCompiler;
    }

    /**
     *
     * @param filePath java源文件目录
     * @param targetDir 编译后class文件的输出目录
     * @param sourceDir 待编译的文件
     * @param encoding 编码格式
     * @param jarPath 依赖的jar路径
     * @throws Exception
     */
    public static void compiler( String filePath, String targetDir, String sourceDir,String encoding, String jarPath)
            throws Exception {

        // 得到filePath目录下的所有java源文件
        List<File> sourceFileList = File4ComplierUtils.getSourceFiles(filePath);

        if (sourceFileList.size() == 0) {
            // 没有java文件,直接返回
            System.out.println(filePath + "目录下查找不到任何java文件");
            return;
        }
        //获取所有jar
        String jars = File4ComplierUtils.getJarFiles(jarPath);
        if(StringUtils.isBlank(jars)){
            jars="";
        }
        File targetFile = new File(targetDir);
        if(!targetFile.exists())targetFile.mkdirs();
        // 建立DiagnosticCollector对象
        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
        //该文件管理器实例的作用就是将我们需要动态编译的java源文件转换为getTask需要的编译单元
        StandardJavaFileManager fileManager = getJavaCompiler().getStandardFileManager(diagnostics, null, null);
        // 获取要编译的编译单元
        Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFileList);
        /**
         * 编译选项,在编译java文件时,编译程序会自动的去寻找java文件引用的其他的java源文件或者class。 -sourcepath选项就是定义java源文件的查找目录, -classpath选项就是定义class文件的查找目录,-d就是编译文件的输出目录。
         */
        Iterable<String> options = Arrays.asList("-encoding",encoding,"-classpath",jars,"-d", targetDir, "-sourcepath", sourceDir);
        /**
         * 第一个参数为文件输出,这里我们可以不指定,我们采用javac命令的-d参数来指定class文件的生成目录
         * 第二个参数为文件管理器实例  fileManager
         * 第三个参数DiagnosticCollector diagnostics是在编译出错时,存放编译错误信息
         * 第四个参数为编译命令选项,就是javac命令的可选项,这里我们主要使用了-d和-sourcepath这两个选项
         * 第五个参数为类名称
         * 第六个参数为上面提到的编译单元,就是我们需要编译的java源文件
         */
        JavaCompiler.CompilationTask task = getJavaCompiler().getTask(
                null,
                fileManager,
                diagnostics,
                options,
                null,
                compilationUnits);
        // 运行编译任务
        // 编译源程式
        boolean success = task.call();
        for (Diagnostic diagnostic : diagnostics.getDiagnostics())
            System.out.printf(
                    "Code: %s%n" +
                            "Kind: %s%n" +
                            "Position: %s%n" +
                            "Start Position: %s%n" +
                            "End Position: %s%n" +
                            "Source: %s%n" +
                            "Message: %s%n",
                    diagnostic.getCode(), diagnostic.getKind(),
                    diagnostic.getPosition(), diagnostic.getStartPosition(),
                    diagnostic.getEndPosition(), diagnostic.getSource(),
                    diagnostic.getMessage(null));
        fileManager.close();
        System.out.println((success)?"编译成功":"编译失败");
    }
}

2.将指定目录下的class文件打入到jar包中

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

// 将指定目录下的class文件打入到jar包中
public class CreateJarUtils {
 
    /**
     * @param rootPath    存放class文件根目录
     * @param targetPath  需要将jar存放的路径
     * @param jarFileName jar文件的名称
     * @Description: 根据class生成jar文件
     * @Author zhangchengping
     * @Date 2019-06-06 23:56
     */
    public static void createTempJar(String rootPath, String targetPath, String jarFileName) throws IOException {
        if (!new File(rootPath).exists()) {
            throw new IOException(String.format("%s路径不存在", rootPath));
        }
        if (StringUtils.isBlank(jarFileName)) {
            throw new NullPointerException("jarFileName为空");
        }
        //生成META-INF文件
        Manifest manifest = new Manifest();
        manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
        //manifest.getMainAttributes().putValue("Main-Class", "Show");//指定Main Class
        //创建临时jar
        File jarFile = File.createTempFile("edwin-", ".jar", new File(System.getProperty("java.io.tmpdir")));
        JarOutputStream out = new JarOutputStream(new FileOutputStream(jarFile), manifest);
        createTempJarInner(out, new File(rootPath), "");
        out.flush();
        out.close();
        //程序结束后,通过以下代码删除生成的jar文件
       /* Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                jarFile.delete();
            }
        });*/
        //生成目标路径
        File targetFile = new File(targetPath);
        if (!targetFile.exists()) targetFile.mkdirs();
        File targetJarFile = new File(targetPath + File.separator + jarFileName + ".jar");
        if(targetJarFile.exists() && targetJarFile.isFile())targetJarFile.delete();
        FileUtils.moveFile(jarFile, targetJarFile);
        //jarFile.renameTo(new File(""));
    }
 
    /**
     * @Description: 生成jar文件
     * @param out 文件输出流
     * @param f 文件临时File
     * @param base 文件基础包名
     * @return void
     * @Author zhangchengping
     * @Date 2019-06-07 00:02
     */
    private static void createTempJarInner(JarOutputStream out, File f,
                                           String base) throws IOException {
 
        if (f.isDirectory()) {
            File[] fl = f.listFiles();
            if (base.length() > 0) {
                base = base + "/";
            }
            for (int i = 0; i < fl.length; i++) {
                createTempJarInner(out, fl[i], base + fl[i].getName());
            }
        } else {
            out.putNextEntry(new JarEntry(base));
            FileInputStream in = new FileInputStream(f);
            byte[] buffer = new byte[1024];
            int n = in.read(buffer);
            while (n != -1) {
                out.write(buffer, 0, n);
                n = in.read(buffer);
            }
            in.close();
        }
    }
}

3.先生成class在生成jar的工具类,对外使用

import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;

public class BuildJarUtil {
    //资源文件根路径
    static String basePath = "x:\\xxxx\\xxxx\\xxxx";

    //java源文件、生成class的文件的根路径,生成jar文件路径
    static String jarFilePath = "x:\\xxxx\\xxxx\\xxxx";

    //需要编译的java源文件路径
    static String[] srcFiles = {
            "/xxxx/xxxx/"
    };

    // 项目中用到的jar包的路径
    static String jarReyOnPath = "x:\\xxxx\\xxxx\\lib";
    // 生成的jar包的路径
    static String jarFileName = "xxxx";
    static String encoding = "utf-8";
 
    public static void main(String[] args) {
        String sourcePath = "";
        String classPath = "";
        try {
            // 需要使用的JAVA文件拷贝到制定目录中
            System.out.println("分隔符:" + File.separator);
            System.out.println("资源拷贝......");
            sourcePath = jarFilePath + File.separator + "source";
            copySource(sourcePath);//拷贝资源
            System.out.println("资源拷贝结束");
            System.out.println("编译资源......");
            //编译java文件
            classPath = jarFilePath + File.separator + "class";
            try {
                CompilerUtil.compiler(sourcePath, classPath, basePath, encoding, jarReyOnPath);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("编译资源结束");
            System.out.println("生成jar......");
            //生成jar文件
            CreateJarUtils.createTempJar(classPath, jarFilePath, jarFileName);
            System.out.println("生成jar完成");
            //删除临时文件
            ExeSuccess(sourcePath, classPath);
        } catch (IOException e) {
            e.printStackTrace();
            deleteTempFile(sourcePath, classPath);
        } finally {
        }
    }
 
    private static void ExeSuccess(String sourcePath, String classPath) {
        final String sourcedir = sourcePath;
        final String classdir = classPath;
        //程序结束后,通过以下代码删除生成的文件
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                deleteTempFile(sourcedir, classdir);
                System.out.println("***************执行完毕**********************");
            }
        });
    }
 
    private static void deleteTempFile(String sourcePath, String classPath) {
        //程序结束后,通过以下代码删除生成的class 和java文件
        try {
            File sourceFile = new File(sourcePath);
            if (sourceFile.exists()) {
                FileUtils.deleteDirectory(sourceFile);
            }
            File classFile = new File(classPath);
            if (classFile.exists()) {
                FileUtils.deleteDirectory(classFile);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    private static void copySource(String sourcePath) throws IOException {
        for (String f : srcFiles) {
            String path = f.replace("/", File.separator);
            System.out.println(path);
            File srcFile = new File(basePath + path);
            File targetFile = new File(sourcePath + path);
            FileUtils.copyDirectory(srcFile, targetFile, new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    System.out.println(pathname);
                    return pathname.getName().endsWith(".java");
                }
            });
        }
    }
}
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class File4ComplierUtils {
 
    /**
     * @Description:  获取目录下所有源文件
     * @param sourceFilePath
     * @return java.util.List
     * @Author zhangchengping
     * @Date 2019-06-06 19:47
     */
    public static List<File> getSourceFiles(String sourceFilePath){
 
        List<File> sourceFileList = new ArrayList<File>();
        try {
            getSourceFiles(new File(sourceFilePath),sourceFileList);
        } catch (Exception e) {
            e.printStackTrace();
            sourceFileList = null;
        }
        return sourceFileList;
    }
 
    /**
     * @Description:  获取目录下所有的jar
     * @param sourceFilePath
     * @return java.lang.String
     * @Author zhangchengping
     * @Date 2019-06-06 19:46
     */
    public static String getJarFiles(String sourceFilePath){
 
        String jars = "";
        try {
            getJarFiles(new File(sourceFilePath),jars);
        } catch (Exception e) {
            e.printStackTrace();
            jars = "";
        }
        return jars;
    }
    /**
     * 查找该目录下的所有的java文件
     *
     * @param sourceFile
     * @param sourceFileList
     * @throws Exception
     */
    private static void getSourceFiles(File sourceFile, List<File> sourceFileList) throws Exception {
        if (!sourceFile.exists()) {
            // 文件或者目录必须存在
            throw new IOException(String.format("%s目录不存在",sourceFile.getPath()));
        }
        if (null == sourceFileList) {
            // 若file对象为目录
            throw new NullPointerException("参数异常");
        }
        if (sourceFile.isDirectory()) {// 若file对象为目录
            File[] childrenDirectoryFiles = sourceFile.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return pathname.isDirectory();
                }
            });
            for (File file : sourceFile.listFiles()) {
                if(file.isDirectory()){
                    getSourceFiles(file,sourceFileList);
                } else {
                    sourceFileList.add(file);
                }
            }
        }else{
            sourceFileList.add(sourceFile);
        }
    }
 
    /**
     * 查找该目录下的所有的jar文件
     *
     * @param sourceFile
     * @throws Exception
     */
    private static String getJarFiles(File sourceFile,String jars) throws Exception {
        if (!sourceFile.exists()) {
            // 文件或者目录必须存在
            throw new IOException("jar目录不存在");
        }
        if (!sourceFile.isDirectory()) {
            // 若file对象为目录
            throw new IOException("jar路径不为目录");
        }
        if(sourceFile.isDirectory()){
            for (File file : sourceFile.listFiles()) {
                if(file.isDirectory()){
                    getJarFiles(file,jars);
                }else {
                    jars = jars + file.getPath() + ";";
                }
            }
        }else{
            jars = jars + sourceFile.getPath() + ";";
        }
        return jars;
    }
}

你可能感兴趣的:(java基础,java,jar,开发语言)