Spring Boot打JAR包运行提示No such file or directory找不到证书文件怎么解决
问题根因
本地开发时mvn spring-boot:run的工作目录是项目根目录,所以能直接读取相对路径下的cert文件夹;但打成JAR包后,JAR是独立的归档文件,要么cert目录未被打进JAR包,要么普通文件IO无法直接读取JAR内部的资源路径,因此会触发文件找不到的报错。
解决方案
你可以根据证书的使用场景选择以下两种方案:
方案1:证书内置到JAR包(适合固定不变的公开证书)
该方案不需要额外维护外部文件,打包后直接运行即可:
- 把整个
cert文件夹移动到项目的src/main/resources目录下,Maven打包时会自动将cert目录下的文件打入JAR的classes目录。 - 修改
@Value注解的默认路径,添加classpath:前缀标识是类路径资源:
@Value("${2c2p.payment-action-api.encrypt-key-file.path:classpath:cert/demo/demo2.crt}") private String encryptKeyFilePath; @Value("${2c2p.payment-action-api.decrypt-key-file.path:classpath:cert/demo/demo2.pfx}") private String decryptKeyFilePath;
- 修改资源读取逻辑,不能直接用文件路径读取,改用Spring的
ResourceLoader加载类路径资源:
// 注入资源加载器 @Autowired private ResourceLoader resourceLoader; private String encrypt(String message) throws CertificateException, IOException { Resource certResource = resourceLoader.getResource(encryptKeyFilePath); // 直接传入输入流给证书读取方法,建议同步修改getPublicCert方法支持InputStream入参 String base64Str = pk.encryptMessage(message, pk.getPublicCert(certResource.getInputStream())); return base64Str; }
如果getPublicCert方法暂时无法修改支持输入流,可以将资源流临时写入系统临时文件,再传递临时文件的路径即可。
方案2:证书放到JAR包外部(适合需要频繁更换、涉密的私有证书)
该方案不需要修改业务代码,仅调整部署结构即可:
- 打包后将
cert文件夹放到和JAR包同级的目录下,运行JAR时的工作目录为JAR所在目录,原有相对路径配置可直接生效。 - 如果需要自定义证书存放路径,可以在
application.properties中添加对应配置:
# 示例:证书存放在服务器/opt/app/cert目录下 2c2p.payment-action-api.encrypt-key-file.path=/opt/app/cert/demo/demo2.crt 2c2p.payment-action-api.decrypt-key-file.path=/opt/app/cert/demo/demo2.pfx
也可以在启动JAR时通过命令行参数动态覆盖配置,无需修改配置文件:
java -jar 你的应用包名.jar --2c2p.payment-action-api.encrypt-key-file.path=/opt/app/cert/demo/demo2.crt --2c2p.payment-action-api.decrypt-key-file.path=/opt/app/cert/demo/demo2.pfx
内容的提问来源于stack exchange,提问作者Hikaru Shindo
相关产品推荐
相关产品推荐

