Maven构建JAR包后运行时无法找到JSON文件路径的求助
问题分析与解决方案
核心原因
本地运行时,程序工作目录是项目根目录,src/main/resources/database/database.json这个文件系统路径确实存在;但打包成JAR后:
src/main/resources下的文件会被编译到JAR包的classpath根目录(路径变为/database/database.json),原文件系统的src/main/resources结构在JAR外部不存在。File类访问的是操作系统的文件系统路径,而非JAR内部的classpath资源,运行JAR时的工作目录没有src/main/resources这个层级,因此抛出找不到路径的异常。- 额外注意:JAR包是只读格式,无法直接修改内部的文件,所以即使能找到JAR里的JSON文件,也无法写入内容。
可行解决方案(支持读写操作)
由于需要对JSON文件进行写入操作,必须将文件放在JAR包外部的文件系统中,同时可以保留初始数据的复制逻辑:
1. 修改代码逻辑
将文件路径改为JAR所在目录下的database/database.json,并添加初始文件复制逻辑(从JAR的classpath中复制默认数据):
private static File getJsonFile() { // 创建JAR所在目录下的database文件夹 File dataDir = new File("database"); if (!dataDir.exists()) { dataDir.mkdirs(); // 递归创建多级目录 } File jsonFile = new File(dataDir, "database.json"); if (!jsonFile.exists()) { try { // 从classpath中读取初始的database.json并复制到外部文件 try (InputStream defaultStream = Database.class.getResourceAsStream("/database/database.json"); OutputStream fileStream = new FileOutputStream(jsonFile)) { if (defaultStream != null) { // 字节流复制文件 byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = defaultStream.read(buffer)) != -1) { fileStream.write(buffer, 0, bytesRead); } } else { // 若没有初始文件,创建空文件 jsonFile.createNewFile(); } } } catch (IOException e) { e.printStackTrace(); } } return jsonFile; }
2. 确保初始文件被正确打包
Maven默认会将src/main/resources下的所有文件打包到JAR的classpath根目录,你的pom.xml无需额外配置,database/database.json会被正确包含在JAR中。
3. 重新打包运行
执行原打包命令:
mvn clean compile assembly:single
运行JAR时,程序会在JAR所在目录自动创建database文件夹和database.json文件(如果不存在),后续读写操作都基于这个外部文件。
补充说明(只读场景)
如果仅需要读取JSON文件(无需写入),可以直接通过classpath资源流访问:
// 读取JAR内部的classpath资源 try (InputStream inputStream = Database.class.getResourceAsStream("/database/database.json")) { if (inputStream != null) { // 处理输入流(比如用Jackson解析JSON) ObjectMapper mapper = new ObjectMapper(); YourDataModel model = mapper.readValue(inputStream, YourDataModel.class); } } catch (IOException e) { e.printStackTrace(); }
但此方案不支持写入操作,因为JAR内部文件无法修改。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

