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()); } } }
额外优化建议
- 目录合法性检查:遍历前先验证依赖目录和源码目录是否存在,避免空指针异常:
// 检查依赖目录 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); }
- 补全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
相关产品推荐
相关产品推荐

