Repackager.java:核心重新打包工具,支持解压、修改合并和重新打包JAR文件

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>() {
            @Override
            public 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>() {
                @Override
                public 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;
                }
                
                @Override
                public 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>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    Files.delete(file);
                    return FileVisitResult.CONTINUE;
                }
                
                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                    Files.delete(dir);
                    return FileVisitResult.CONTINUE;
                }
            });
        }
    }
}

 以下是将指定路径的JAR包集成到程序中的完整解决方案。

import java.io.*;
import java.nio.file.*;
import java.util.jar.*;
import java.net.URL;
import java.net.URLClassLoader;

public class JarIntegrator {
    // 配置的JAR包路径
    private static final String JAR_PATH = "C:\\Users\\e005716\\Desktop\\ydn生成ppt\\配置文件\\jar包";
    
    public static void main(String[] args) {
        System.out.println("JAR包集成工具启动...");
        System.out.println("配置的JAR路径: " + JAR_PATH);
        
        try {
            // 检查JAR包路径是否存在
            Path jarPath = Paths.get(JAR_PATH);
            if (!Files.exists(jarPath)) {
                System.err.println("错误: 指定的JAR包路径不存在");
                return;
            }
            
            // 如果是目录,列出其中的JAR文件
            if (Files.isDirectory(jarPath)) {
                System.out.println("目录中的JAR文件:");
                Files.list(jarPath)
                    .filter(path -> path.toString().endsWith(".jar"))
                    .forEach(path -> System.out.println("  " + path.getFileName()));
            } 
            // 如果是文件,验证是否为有效的JAR文件
            else {
                validateJarFile(jarPath.toFile());
            }
            
            // 动态加载JAR包示例
            loadAndExecuteJar(JAR_PATH);
            
        } catch (Exception e) {
            System.err.println("处理JAR包时出错: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 验证JAR文件是否有效
     */
    private static void validateJarFile(File jarFile) throws IOException {
        try (JarFile jar = new JarFile(jarFile)) {
            System.out.println("JAR文件验证成功: " + jarFile.getName());
            System.out.println("条目数量: " + jar.size());
        } catch (Exception e) {
            throw new IOException("无效的JAR文件: " + jarFile.getName(), e);
        }
    }
    
    /**
     * 动态加载并执行JAR包中的类
     */
    private static void loadAndExecuteJar(String jarPath) {
        try {
            File jarFile = new File(jarPath);
            if (!jarFile.exists()) {
                System.out.println("JAR文件不存在: " + jarPath);
                return;
            }
            
            // 创建类加载器
            URL[] urls = {jarFile.toURI().toURL()};
            URLClassLoader classLoader = new URLClassLoader(urls);
            
            System.out.println("JAR包已成功加载到程序中");
            System.out.println("可以通过classLoader加载其中的类");
            
            // 关闭类加载器
            classLoader.close();
            
        } catch (Exception e) {
            System.err.println("加载JAR包失败: " + e.getMessage());
        }
    }
}

 

posted @ 2026-01-21 13:09  血月葬花魂  阅读(2)  评论(0)    收藏  举报