Spring Boot部署Heroku读取静态JSON文件编译报错
问题根因
当前报错和文件定位无关,是两个问题共同导致的:
- 编译错误直接原因:
Path.of()、Files.readString()是Java 11及以上版本才新增的API,Heroku默认构建时使用的JDK版本低于11,无法识别这两个方法,直接编译失败。 - 现有文件路径写法存在隐患:硬编码
src/main/resources/data/FUNDOS.json属于本地开发环境的巧合适配,项目打包部署后src/main目录结构不会保留,resources下的文件会直接归入classpath路径,哪怕解决了JDK版本问题,部署后依然会报文件不存在。
解决步骤
1. 指定Heroku构建环境的JDK版本
在项目根目录(和pom.xml或build.gradle同级)新建system.properties配置文件,写入和本地开发环境一致的JDK版本,例如本地使用Java 11则配置:
java.runtime.version=11
如果本地使用Java 17,将版本号改为17即可,避免出现版本兼容问题。
2. 替换资源文件读取逻辑
不要通过硬编码文件系统路径读取resources目录下的静态文件,使用类路径方式读取,以下两种方案任选其一即可:
方案1:Java 11+ 简洁写法
借助Spring内置的资源工具类读取,代码改动量最小:
import org.springframework.util.ResourceUtils; import java.nio.file.Files; import java.nio.file.Path; import org.json.JSONArray; import java.io.File; // classpath: 对应resources目录的根路径 File jsonFile = ResourceUtils.getFile("classpath:data/FUNDOS.json"); String jsonString = Files.readString(Path.of(jsonFile.getAbsolutePath())); JSONArray json = new JSONArray(jsonString);
方案2:全场景兼容稳妥写法
通过类加载器读取资源流,不受部署环境、打包方式影响,是读取静态资源的通用标准写法,Spring项目可直接用内置工具类处理流转换,无需额外引入依赖:
import java.io.InputStream; import java.nio.charset.StandardCharsets; import org.springframework.util.StreamUtils; import org.json.JSONArray; InputStream is = getClass().getClassLoader().getResourceAsStream("data/FUNDOS.json"); String jsonString = StreamUtils.copyToString(is, StandardCharsets.UTF_8); JSONArray json = new JSONArray(jsonString);
注意:类路径写法不要在路径前额外加斜杠,
data/FUNDOS.json为正确格式。
改完后先在本地验证读取正常,再将代码和新增的system.properties文件一同提交推送到Heroku即可正常构建运行。
内容的提问来源于stack exchange,提问作者Guilherme Gonzalez
相关产品推荐
相关产品推荐

