import java.io.*; import java.util.jar.*; import java.util.zip.*; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.List;public class Repackager {public static void main(String[] args) {if (args.length < 2) {System.out.println("用法: java Repackager <原JAR路径> <新JAR路径> [修改文件夹]");return;}String originalJar = args[0];String newJar = args[1];String modificationDir = args.length > 2 ? args[2] : null;try {repackJar(originalJar, newJar, modificationDir);System.out.println("JAR包重新打包完成: " + newJar);} catch (Exception e) {System.err.println("重新打包失败: " + e.getMessage());e.printStackTrace();}}public static void repackJar(String originalJar, String newJar, String modificationDir) throws IOException {// 创建临时目录用于解压Path tempDir = Files.createTempDirectory("jar_repack_");try {// 解压原JAR包 extractJar(originalJar, tempDir);// 如果提供了修改目录,则合并修改内容if (modificationDir != null) {mergeModifications(tempDir, modificationDir);}// 重新打包 createJar(newJar, tempDir);} finally {// 清理临时目录 deleteRecursively(tempDir);}}private static void extractJar(String jarPath, Path destDir) throws IOException {try (JarInputStream jarIn = new JarInputStream(new FileInputStream(jarPath))) {JarEntry entry;while ((entry = jarIn.getNextJarEntry()) != null) {Path entryPath = destDir.resolve(entry.getName());if (entry.isDirectory()) {Files.createDirectories(entryPath);} else {Files.createDirectories(entryPath.getParent());Files.copy(jarIn, entryPath, StandardCopyOption.REPLACE_EXISTING);}}}}private static void mergeModifications(Path baseDir, String modDir) throws IOException {Path modPath = Paths.get(modDir);if (!Files.exists(modPath)) {System.out.println("修改目录不存在: " + modDir);return;}Files.walkFileTree(modPath, new SimpleFileVisitor<Path>() {@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {Path relativePath = modPath.relativize(file);Path targetPath = baseDir.resolve(relativePath);Files.createDirectories(targetPath.getParent());Files.copy(file, targetPath, StandardCopyOption.REPLACE_EXISTING);return FileVisitResult.CONTINUE;}});}private static void createJar(String jarPath, Path sourceDir) throws IOException {try (JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(jarPath))) {Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {String entryName = sourceDir.relativize(file).toString().replace('\\', '/');jarOut.putNextEntry(new JarEntry(entryName));Files.copy(file, jarOut);jarOut.closeEntry();return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {String entryName = sourceDir.relativize(dir).toString().replace('\\', '/') + "/";jarOut.putNextEntry(new JarEntry(entryName));jarOut.closeEntry();return FileVisitResult.CONTINUE;}});}}private static void deleteRecursively(Path path) throws IOException {if (Files.exists(path)) {Files.walkFileTree(path, new SimpleFileVisitor<Path>() {@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {Files.delete(file);return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {Files.delete(dir);return FileVisitResult.CONTINUE;}});}} }