当前位置: 首页 > news >正文

解决应用程序在JAR包中运行时无法读取类路径下文件的问题

问题情景

java应用程序在IDE运行正常,打成jar包后执行却发生异常:

java.io.FileNotFoundException: class path resource [cert/sync_signer_pri_test.key] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/home/apps/application.jar!/BOOT-INF/classes!/cert/sync_signer_pri_test.key
at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:217)
at org.springframework.core.io.AbstractFileResolvingResource.getFile(AbstractFileResolvingResource.java:162)
at com.cfgdc.school.utils.JwtUtils.loadSyncSignerPrivateKey(JwtUtils.java:161)

上述错误信息指出文件路径是class path resource [cert/sync_signer_pri_test.key],但无法解析为绝对路径,因为它不在文件系统中,而是在一个jar包内。

这个文件在IDE中的位置是:src/main/resources/cert/sync_signer_pri_test.key,
打成jar包以后的位置是:/home/apps/application.jar!/BOOT-INF/classes!/cert/sync_signer_pri_test.key,并不是文件系统中的一个实际文件,而是一个可以通过类加载器读取的条目

原因分析

当应用程序打包成jar文件后,资源文件通常会被包含在jar内部。这时候,使用传统的File来访问资源文件可能会失败,因为jar中的资源并不是文件系统中的一个实际文件,而是一个可以通过类加载器读取的条目。

解决方案

要解决应用程序在JAR包中运行时无法读取类路径下文件的问题,需调整文件读取方式,使用流(InputStream)代替直接文件访问
使用这种方式,既可以在IDE直接运行,也可以打成jar包运行。

以下是具体步骤:

步骤一:修改文件读取方式

JwtUtils类的loadSyncSignerPrivateKey方法中,将使用Resource.getFile()的代码替换为通过InputStream读取:

import org.springframework.core.io.ClassPathResource;
import org.apache.commons.io.IOUtils;// 修改前的代码(导致异常)
// File file = new ClassPathResource("cert/sync_signer_pri_test.key").getFile();// 修改后的代码
try (InputStream inputStream = new ClassPathResource("cert/sync_signer_pri_test.key").getInputStream()) {String privateKeyContent = IOUtils.toString(inputStream, StandardCharsets.UTF_8);// 处理privateKeyContent,例如加载私钥
} catch (IOException e) {// 异常处理
}

步骤二:确保依赖项正确

如果使用Apache Commons IO的IOUtils,需在pom.xml中添加依赖:

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version>
</dependency>

步骤三:重新打包并测试

重新构建应用并打包为JAR,运行测试以确认问题已解决。

替代方案:外部化配置文件

若希望将证书文件放在JAR外部:

  1. 将文件移至外部目录,如/home/config/cert/sync_signer_pri_test.key
  2. 修改配置读取路径,使用绝对路径或通过环境变量指定路径:
String externalConfigPath = System.getenv("CONFIG_PATH") + "/cert/sync_signer_pri_test.key";
File file = new File(externalConfigPath);
  1. 确保部署时正确设置环境变量或路径,并授予读取权限。

总结

优先采用流方式读取类路径资源,确保JAR内资源正确访问。若需外部配置,调整文件位置并修改读取路径。修改后重新部署应用即可解决问题。

相关文章:

  • SSH(安全外壳协议)
  • 软件安全(二)优化shellcode
  • FreeRTOS如何实现100%的硬实时性?
  • 龙虎榜——20250509
  • 编译原理实验 之 语法分析程序自动生成工具Yacc实验
  • nvidia-smi 和 nvcc -V 作用分别是什么?
  • 算法设计与分析复习代码(hnust)
  • LVGL源码学习之渲染、更新过程(3)---绘制和刷写
  • 操作系统导论——第26章 并发:介绍
  • 68、微服务保姆教程(十一)微服务的监控与可观测性
  • 专题练习1
  • 赤色世界 陈默传 第一章 另一个陈默
  • 路由组件1
  • java volatile关键字
  • 二分系列题
  • 什么是AIOps
  • TDengine 在智慧油田领域的应用
  • 多序列比对软件 Clustal Omega 介绍
  • 嵌入式培训之C语言学习完(十七)结构体、共用体、枚举、typedef关键字与位运算
  • 信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(十二)
  • 卢正已任上海市司法局党委委员、副局长
  • 重庆大学:对学术不端行为“零容忍”,发现一例、查处一例
  • 中国一重集团有限公司副总经理陆文俊被查
  • 国家发改委:美芯片药品等领域关税影响全球科技发展,损害人类共同利益
  • 习近平同俄罗斯总统普京会谈
  • 老铺黄金拟配售募资近27亿港元,用于门店拓展扩建及补充流动资金等