You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Jar导出工具编译报错:多源文件路径处理问题求助

问题诊断与修复方案

核心问题

编译失败的根源在于compile()方法对JavaCompiler.run()的参数传递错误:你把所有源文件路径用String.join(" ", s_sourceFiles)拼接成单个字符串传入,但run()方法的可变参数要求每个源文件路径是独立的参数项。javac会将这个拼接后的长字符串识别为一个不存在的文件名,因此抛出"Invalid filename"错误。

修复代码

1. 修正编译参数传递逻辑

修改compile()方法,将源文件列表作为独立参数传递给编译器:

private static int compile() {
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    // 构造完整的编译参数列表
    List<String> compileArgs = new ArrayList<>();
    compileArgs.add("-d");
    compileArgs.add(PROJECT_DIR + File.separator + "bin");
    compileArgs.add("-cp");
    compileArgs.add(String.join(File.pathSeparator, s_classpath));
    // 将每个源文件路径作为独立参数加入
    compileArgs.addAll(s_sourceFiles);
    
    // 转换为数组传递给run方法
    return compiler.run(null, null, null, compileArgs.toArray(new String[0]));
}

2. 过滤非Java源文件

当前代码会把目录下所有文件加入源列表,包括非.java文件,需添加过滤逻辑:

private static void addSourceFiles(File file) {
    if (file.isDirectory()) {
        File[] files = file.listFiles();
        if (files != null) {
            for (File f : files) {
                addSourceFiles(f);
            }
        }
    } else {
        // 仅添加.java后缀的源码文件
        if (file.getName().endsWith(".java")) {
            s_sourceFiles.add(file.getPath());
            System.out.println("Added source file: " + file.getPath());
        }
    }
}

额外优化建议

  1. 目录合法性检查:遍历前先验证依赖目录和源码目录是否存在,避免空指针异常:
// 检查依赖目录
File dependenciesDir = new File(DEPENDENCIES_DIR);
if (!dependenciesDir.exists() || !dependenciesDir.isDirectory()) {
    System.err.println("依赖目录不存在:" + DEPENDENCIES_DIR);
    System.exit(1);
}

// 检查源码目录
File srcDir = new File(SRC_DIR);
if (!srcDir.exists() || !srcDir.isDirectory()) {
    System.err.println("源码目录不存在:" + SRC_DIR);
    System.exit(1);
}
  1. 补全Jar导出逻辑:实现exportJar()方法完成Jar包生成:
private static void exportJar() {
    String jarPath = PROJECT_DIR + File.separator + "output.jar";
    File binDir = new File(PROJECT_DIR + File.separator + "bin");
    
    try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarPath), manifest)) {
        addFilesToJar(binDir, binDir, jos);
        System.out.println("Jar包已导出至:" + jarPath);
    } catch (IOException e) {
        System.err.println("Jar包导出失败:" + e.getMessage());
        System.exit(1);
    }
}

private static void addFilesToJar(File baseDir, File currentFile, JarOutputStream jos) throws IOException {
    if (currentFile.isDirectory()) {
        File[] files = currentFile.listFiles();
        if (files != null) {
            for (File f : files) {
                addFilesToJar(baseDir, f, jos);
            }
        }
    } else {
        // 计算Jar内的相对路径
        String entryName = baseDir.toURI().relativize(currentFile.toURI()).getPath();
        JarEntry entry = new JarEntry(entryName);
        jos.putNextEntry(entry);
        
        try (FileInputStream fis = new FileInputStream(currentFile)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                jos.write(buffer, 0, bytesRead);
            }
        }
        jos.closeEntry();
    }
}

内容的提问来源于stack exchange,提问作者Temps

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 14:16:47