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

AWS EC2服务器从公共Jar资源获取File对象时遇FileNotFoundException

解决Jar内部资源无法转为File对象的问题

Hey there! Let's break down why this is happening and get it fixed for you.

问题根源

你遇到的核心问题是:Jar包内部的资源并不是文件系统里的独立物理文件。在Eclipse开发环境中,你的key.pem是直接放在项目classpath目录下的真实文件,所以getResource()返回的是file:协议的URI,能顺利转成File对象。但当项目打包成Jar(包括依赖的公共Jar)后,key.pem变成了Jar包内的一个条目,此时getResource()返回的是jar:协议的URI,Paths.get(res.toURI())无法识别这种格式,自然就抛出FileNotFoundException——EC2上运行的是打包后的Jar,所以问题就暴露出来了。

解决方案

根据你的需求,分两种场景处理:

1. 必须使用File对象(比如某些API强制要求)

如果业务代码一定要用File对象,可以把Jar里的资源复制到临时文件中,再使用这个临时文件:

try {
    // 获取资源的输入流
    InputStream inputStream = ResidentHelperService.class.getClassLoader().getResourceAsStream("key.pem");
    if (inputStream == null) {
        throw new RuntimeException("资源文件key.pem不存在");
    }

    // 创建临时文件,保留.pem后缀
    File tempFile = File.createTempFile("temp-key", ".pem");
    // 程序正常退出时自动删除临时文件
    tempFile.deleteOnExit();

    // 将输入流内容复制到临时文件
    Files.copy(inputStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

    // 现在tempFile就是可用的File对象了
    System.out.println("临时文件路径:" + tempFile.getAbsolutePath());
} catch (IOException e) {
    e.printStackTrace();
}

2. 可以改用InputStream(推荐)

如果你的业务代码能接受InputStream(大多数处理文件的API都支持),直接用getResourceAsStream()获取输入流是最简单高效的方式,完全避开File对象的限制:

InputStream pemStream = ResidentHelperService.class.getClassLoader().getResourceAsStream("key.pem");
if (pemStream == null) {
    throw new RuntimeException("资源文件key.pem不存在");
}
// 直接用pemStream进行后续操作,比如读取密钥内容等

额外提示

  • 可以解压依赖的project-common-utilityJar包,确认key.pem确实被打包到了BOOT-INF/lib/project-common-utility-0.0.1-SNAPSHOT.jar!/key.pem路径下,避免资源漏打包的情况。
  • 临时文件方案虽然能解决File对象的需求,但会产生临时文件,deleteOnExit()能保证JVM正常退出时清理,若程序异常退出可能会残留文件,必要时可以手动添加清理逻辑。

内容的提问来源于stack exchange,提问作者Supriya Shelar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:12:51