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

Maven构建JAR包后运行时无法找到JSON文件路径的求助

问题分析与解决方案

核心原因

本地运行时,程序工作目录是项目根目录,src/main/resources/database/database.json这个文件系统路径确实存在;但打包成JAR后:

  1. src/main/resources下的文件会被编译到JAR包的classpath根目录(路径变为/database/database.json),原文件系统的src/main/resources结构在JAR外部不存在。
  2. File类访问的是操作系统的文件系统路径,而非JAR内部的classpath资源,运行JAR时的工作目录没有src/main/resources这个层级,因此抛出找不到路径的异常。
  3. 额外注意: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:37:26