Jar包内的可执行文件无法被ProcessBuilder找到
解决Jar包中调用外部exe文件的路径问题
核心问题在于:打包进Jar的exe文件是压缩包内的资源,不是本地文件系统上的独立文件,ProcessBuilder只能识别本地磁盘的绝对路径,无法直接访问Jar内部的路径。IDE运行正常是因为开发时资源文件被解压到了本地磁盘的目录(比如target/classes),相对路径能直接找到。
解决步骤:把Jar内的exe提取到本地临时目录执行
- 读取Jar中的exe资源流
- 将资源写入本地临时文件
- 使用临时文件的绝对路径调用ProcessBuilder
- 程序结束后自动清理临时文件
示例代码:
import java.io.*; import java.nio.file.Files; public class ExeExecutor { public static void executeTool() throws IOException { // 从Jar根目录读取exe资源,路径开头必须加/ InputStream exeInputStream = ExeExecutor.class.getResourceAsStream("/external/name-of-tool/name-of-tool.exe"); if (exeInputStream == null) { throw new FileNotFoundException("Jar包中未找到目标exe文件"); } // 创建临时文件,后缀为.exe,程序退出时自动删除 File tempExeFile = File.createTempFile("name-of-tool", ".exe"); tempExeFile.deleteOnExit(); // 将资源流写入临时文件 Files.copy(exeInputStream, tempExeFile.toPath()); // 给临时文件添加可执行权限(Windows系统可忽略,Linux/macOS必须设置) tempExeFile.setExecutable(true); // 调用ProcessBuilder执行临时文件 ProcessBuilder processBuilder = new ProcessBuilder(tempExeFile.getAbsolutePath()); processBuilder.inheritIO(); // 将exe的输出/错误流重定向到当前控制台,方便调试 Process process = processBuilder.start(); // 可选:等待exe执行完成 try { process.waitFor(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }
额外注意事项
- Maven打包配置:确保exe文件被正确打包进Jar,在
pom.xml中添加资源配置(如果尚未配置):
<build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.exe</include> </includes> </resource> </resources> </build>
- 临时文件清理:
deleteOnExit()会在JVM正常退出时删除临时文件,如果程序异常崩溃,临时文件可能残留,可根据需求添加手动清理逻辑。
内容的提问来源于stack exchange,提问作者Overdrowsed
相关产品推荐
相关产品推荐

