class path resource [] cannot be resolved to absolute file path
问题情景
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包内。
原因分析
当应用程序打包成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外部:
- 将文件移至外部目录,如
/home/config/cert/sync_signer_pri_test.key
。 - 修改配置读取路径,使用绝对路径或通过环境变量指定路径:
String externalConfigPath = System.getenv("CONFIG_PATH") + "/cert/sync_signer_pri_test.key";
File file = new File(externalConfigPath);
- 确保部署时正确设置环境变量或路径,并授予读取权限。
总结
优先采用流方式读取类路径资源,确保JAR内资源正确访问。若需外部配置,调整文件位置并修改读取路径。修改后重新部署应用即可解决问题。