import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

public class CompileJarUtil {

	public static void main(String[] args) {

//		args = new String[] { "D:\\Workspace\\javaweb-springboot\\BilibiliDown\\", "nicelee.ui.FrameMain" };
		File rootFolder = new File(args[0]);
		String mainClass = args[1];

		File source = new File(rootFolder, "src");
		File libs = new File(rootFolder, "libs");
		File dst = new File(rootFolder, "targets");
		File jar = new File(rootFolder, "INeedBiliAV.jar");
		compileFolder(source, dst, libs, dst);
		compileLibs(libs, dst);
		jar(dst, jar, mainClass);
	}

	static void compileLibs(File libs, File dst) {
		if (!dst.exists()) {
			dst.mkdirs();
		}
		for (File file : libs.listFiles()) {
			if (file.getName().endsWith(".jar")) {
				unJar(file, dst);
			}
		}
	}

	static void compileFolder(File source, File dst, File libs, File root) {
		if (!dst.exists()) {
			dst.mkdirs();
		}
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

		StringBuilder sb = new StringBuilder();
		try {
			sb.append(new File(root.getParentFile(), "src").getCanonicalPath());
			for (File file : libs.listFiles()) {
				if (file.getName().endsWith(".jar")) {
					sb.append(File.pathSeparator).append(file.getCanonicalPath());
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		String classpath = sb.toString();
		for (File file : source.listFiles()) {
			if (file.isDirectory()) {
				if(!file.getName().startsWith("test")) {
					File newDst = new File(dst, file.getName());
					compileFolder(file, newDst, libs, root);
				}
			} else {
				if (file.getName().endsWith(".java")) {
					if(!file.getName().equals("FrameMain.java") && !file.getParentFile().getName().equals("impl")) {
						continue;
					}
					System.out.println(file.getName());
					System.out.println(classpath);
					try {
						compiler.run(null, null, null, "-classpath", classpath, "-encoding", "UTF-8", "-d",
//						compiler.run(null, null, null,  "-encoding", "UTF-8", "-d",
								root.getCanonicalPath(), file.getCanonicalPath());
					} catch (IOException e) {
						// e.printStackTrace();
					}
				} else {
					copy(file, new File(dst, file.getName()));
				}
			}
		}
	}

	static void copy(File source, File dest) {
		try {
			RandomAccessFile rSource = new RandomAccessFile(source, "r");
			RandomAccessFile rDest = new RandomAccessFile(dest, "rw");

			byte[] buffer = new byte[1024 * 1024];
			int size = rSource.read(buffer);
			while (size != -1) {
				rDest.write(buffer, 0, size);
				size = rSource.read(buffer);
			}
			rSource.close();
			rDest.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 解压文件
	 * 
	 * @param jarFile 解压文件
	 * @param dst     输出解压文件路径
	 */
	public static void unJar(File jarFile, File dst) {
		byte[] buffer = new byte[1024];

		if (!dst.exists()) {
			dst.mkdir();
		}
		try {
			JarInputStream zis = new JarInputStream(new FileInputStream(jarFile));
			JarEntry ze = zis.getNextJarEntry();
			while (ze != null) {
				String fileName = ze.getName();
				File newFile = new File(dst, fileName);
				// System.out.println("file unzip : "+ newFile.getAbsoluteFile());
				if (ze.isDirectory()) {
					newFile.mkdirs();
				} else {
					new File(newFile.getParent()).mkdirs();
					FileOutputStream fos = new FileOutputStream(newFile);
					int len;
					while ((len = zis.read(buffer)) != -1) {
						fos.write(buffer, 0, len);
					}
					fos.close();
				}
				ze = zis.getNextJarEntry();
			}
			zis.closeEntry();
			zis.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 压缩文件
	 *
	 * @param sourceFile 源文件路径
	 * @param jarFile    压缩后文件
	 * @param mainClass  入口类
	 */
	public static void jar(File sourceFile, File jarFile, String mainClass) {
		Manifest manifest = new Manifest();
		Attributes attrs = manifest.getMainAttributes();
		attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
		attrs.put(Attributes.Name.CLASS_PATH, ".");
		attrs.put(Attributes.Name.MAIN_CLASS, mainClass);

		try (JarOutputStream zos = new JarOutputStream(new FileOutputStream(jarFile, false), manifest)) {
			for (File file : sourceFile.listFiles()) {
				writeJar(file, "", zos);
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e.getMessage(), e.getCause());
		}
	}

	/**
	 * 遍历所有文件,压缩
	 * <p>
	 * 目录名称必须以“/”斜杠结尾。
	 * </p>
	 * <p>
	 * 路径必须使用'/'斜杠,而不是'\'
	 * </p>
	 * <p>
	 * 条目不能以“/”斜杠开头。
	 * </p>
	 *
	 * @param file       源文件目录
	 * @param parentPath 压缩文件目录
	 * @param zos        文件流
	 */
	public static void writeJar(File file, String parentPath, JarOutputStream zos) {
		if (file.isDirectory()) {
			// 目录
			parentPath += file.getName() + "/";
			JarEntry zipEntry = new JarEntry(parentPath);
			// System.out.println(parentPath);
			try {
				zos.putNextEntry(zipEntry);
			} catch (IOException e) {
				e.printStackTrace();
			}
			File[] files = file.listFiles();
			for (File f : files) {
				writeJar(f, parentPath, zos);
			}
		} else {
			// 文件
			try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
				// 指定jar文件夹
				JarEntry zipEntry = new JarEntry(parentPath + file.getName());
				// System.out.println(parentPath + file.getName());
				zos.putNextEntry(zipEntry);
				int len;
				byte[] buffer = new byte[1024 * 10];
				while ((len = bis.read(buffer, 0, buffer.length)) != -1) {
					zos.write(buffer, 0, len);
					zos.flush();
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException(e.getMessage(), e.getCause());
			}
		}
	}
}
最近下载更多
玖零定制问题修复  LV34 3月3日
woldxy  LV12 2月19日
Seaskye  LV14 2023年11月10日
lipanlong  LV10 2023年7月6日
zhangjilu  LV18 2023年4月23日
wyx065747  LV67 2023年2月6日
快乐的程序员  LV25 2023年1月25日
Rommel  LV27 2022年11月12日
笑得很美  LV11 2022年10月27日
最代码官方  LV167 2022年10月23日
最近浏览更多
WBelong  LV7 3月28日
玖零定制问题修复  LV34 3月3日
3334004690  LV3 2月20日
woldxy  LV12 2月19日
哪里的完整版  LV7 2月1日
linfon  LV2 1月25日
shiaomon 2023年12月14日
暂无贡献等级
Seaskye  LV14 2023年11月10日
wl010101  LV9 2023年11月8日
jkjfdgbkl  LV2 2023年11月1日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友