一、前言
最近在本地部署https服务的时候遇到一个问题。在创建好keystore签名文件之后,完成了一切配置工作。接着在启动的过程中却报错:Invalid keystore format。经过再三确认KeyStore签名文件格式本身并没有问题。接下来就和大家分享下该问题的根源,以及如何解决该问题。
二、根因分析
1、基本原因
遇到疑难杂症Google就比较好的习惯(不要问我为什么不用某度),经过一番搜索之后终于找到了如下同命中人,原文地址:https://stackoverflow.com/questions/57541107/keystore-load-fails-with-invalid-keystore-format。
在该问题后面终于找到了答案(如下)。大概意思就是JKS(KeyStore)文件被Maven Resources插件渗透了,其会导致文件被损坏。其中还提到了一些统一问题的描述。
根据指引我也去看了maven的官方描述(地址:https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html),其中明确通过Warning的方式告诉了我们filter不能使用到二级制文件中,否则会导致文件损坏。并且给了解决办法。
2、根因分析
通过上述的分析,我们知道了这个错误是由于Maven Resources插件的filter属性导致的。那么为什么这个数会导致二级制文件损坏呢?接下来我们来深入分析下。
首先我们要知道filter的作用是什么。根据官方的描述(如下图),我们知道其作用使用就是将被filter的文件中的${}占位符替换为命令行或者pom中的属性值。
因此为了完成整个占位符替换的操作,Maven Resources插件会将所有需要filter的文件都当做文本文件读取,然后去找到${}占位符并替换掉。完成占位符替换之后,再重新将文件内容写回文件。这会导致文件被重新,且格式貌似会被重写为UTF-8。因此这就导致了二级制文件虽然没有占位符,但是还是因为重新回写会修改字符编码导致文件被损坏。
三、解决办法
知道原因之后,我们就可能比较好的处理该问题。目前主要有两种方式处理:
1、二进制资源单独存放一个Resouces文件夹(官方推荐)
这种方法是Maven官方推荐的,地址:https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
即将二进制文件单独存放到一个Resources文件夹中。这样在使用maven resources插件的时候就可以对不同的文件夹做不同的处理(二进制文件夹下的资源不执行filter)。
2、使用exclude过滤不需要filter的文件
这种方法比较粗暴,直接在resource下使用exclude和include来隔离不同的文件,从而对不同的文件采取不同的filter策略。
3、两种方式对比
官方推荐方式:一劳永逸,后续新增的二级机制文件直接放到对应文件夹即可。但是需要由两个resource文件夹
exclude方式:不需要新增resource文件夹,但是后续新增二级机制文件需要修改pom中的resource插件配置。
PS:通过上述分析我们知道该问题是由Maven Resouces插件的filter导致的,和是否使用Spring Boot并无关系!
四、惯例
如果你对本文有任何疑问或者高见,欢迎添加公众号lifeofcoder共同交流探讨(添加公众号可以获得楼主最新博文推送以及”Java高级架构“上10G视频和图文资料哦)。