网站首页 > java教程 正文
Spring Boot JAR 包资源访问踩坑:cannot be resolved to absolute file
temp10 2025-09-13 09:06:26 java教程 3 ℃ 0 评论在 IDE 中运行 Spring Boot 项目,读取 classpath 下的脚本或配置文件,代码运行得顺畅无比。如下:
String content = FileUtils.readFileToString(
new ClassPathResource("config/app-config.yml").getFile(),"utf-8");
但打包成 JAR 部署到服务器后,却抛出这个错误:
class path resource [config/app-config.yml] cannot be resolved to absolute file path
because it does not reside in the file system
看着这行报错,一脸懵:为什么 IDE 正常,JAR 包就不行?
原因分析
在开发环境中(比如 IntelliJ IDEA):资源文件(如
src/main/resources/config/app-config.yml)存储在target/classes 目录下;但项目打包成 Spring Boot 的 Fat JAR 后,资源被压缩到 JAR 包的 BOOT-INF/classes/ 目录,路径变成: jar:file:/app.jar!/BOOT-INF/classes!/config/app-config.yml。
接下来,我们继续分析ClassPathResource.getFile()的源码,如下:
// org.springframework.core.io.AbstractFileResolvingResource#getFile()
public File getFile() throws IOException {
URL url = getURL();
// ResourceUtils.URL_PROTOCOL_VFS = "vfs"
if (url.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
return VfsResourceDelegate.getResource(url).getFile();
}
return ResourceUtils.getFile(url, getDescription());
}
// org.springframework.util.ResourceUtils#getFile(java.net.URL, java.lang.String)
public static File getFile(URL resourceUrl, String description) throws FileNotFoundException {
// URL_PROTOCOL_FILE = "file"
if (!URL_PROTOCOL_FILE.equals(resourceUrl.getProtocol())) {
throw new FileNotFoundException(
description + " cannot be resolved to absolute file path " +
"because it does not reside in the file system: " + resourceUrl);
}
try {
return new File(toURI(resourceUrl).getSchemeSpecificPart());
}
catch (URISyntaxException ex) {
// Fallback for URLs that are not valid URIs (should hardly ever happen).
return new File(resourceUrl.getFile());
}
}
通过源码可知 ClassPathResource.getFile()报错的原因:资源不是 file:// 协议,直接抛异常。
如何解决
1.使用InputStream读取
import org.springframework.core.io.ClassPathResource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class ResourceReader {
public String readScript() throws IOException {
ClassPathResource resource = new ClassPathResource("config/app-config.yml");
try (var inputStream = resource.getInputStream()) {
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
}
}
}
2.转换为临时文件
public class ResourceToFile {
public File convertToFile() throws IOException {
ClassPathResource resource = new ClassPathResource("config/app-config.yml");
Path tempFile = Files.createTempFile("cust-fund-script", ".tmp");
try (var inputStream = resource.getInputStream()) {
Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING);
}
File file = tempFile.toFile();
file.deleteOnExit(); // 自动清理
return file;
}
}
感谢您的阅读!希望这部分内容对您有所启发。如果您觉得有价值,请不吝点赞支持,并在评论区留下您的想法,一起交流学习!别忘了关注我哦!
猜你喜欢
- 2025-09-13 如何将 Spring Boot 应用打包部署为容器镜像,避免环境异常无法部署
- 2025-09-13 SpringBoot动态加载外部Jar:解锁插件化架构的实战指南
- 2025-09-13 SpringBoot构建Jar包实现依赖包分离
- 2025-09-13 Python 打包为 Android 的 APK 文件,环境配置技术要点
- 2025-09-13 Maven打包的时候排除指定的资源、目录、文件和程序类的方法
- 2025-09-13 SpringBoot加载外部Jar实现功能按需扩展
- 2025-09-13 Spring Boot3 全栈打包指南:一键搞定应用、数据库与 Redis 镜像部署
- 2025-09-13 「项目部署」使用Jenkins一键打包部署SpringBoot应用
- 2025-09-13 Spring Boot打包成JAR后,内置Tomcat你真的懂吗?
- 2025-09-13 SpringBoot 多模块项目实践(附打包方法)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)