一次-Djava.ext.dir配置不当的问题

问题描述:

服务新增一个加解密模块后,本地调试OK部署到测试环境启动开始功能测试,却发现相关功能异常,查看服务日志发现以下异常

1
2
3
java.security.NoSuchAlgorithmException: Algorithm HmacSHA256 not available
at javax.crypto.Mac.getInstance(Mac.java:181)
......

问题排查:

服务是springboot的项目,直接打包成jar包,启动脚本中使用java -jar的形式启动。由于用到了一些公司内部封装的依赖jar包,而这些jar必须外部加载不能打进jar里面启动,所以使用了-Djava.ext.dirs去加载外部依赖jar包,这时一个陷阱就出现了,-Djava.ext.dirs会覆盖掉java本身的ext设置,java.ext.dirs指定的目录由ExtClassLoader加载器加载,如果没有指定该系统属性,那么该加载器默认加载$JAVA_HOME/jre/lib/ext目录下的所有jar文件

1
2
3
4
5
6
7
8
9
10
11
-rwxr-xr-x 1    3860502 Mar 15  2017 cldrdata.jar
-rwxr-xr-x 1 8286 Mar 15 2017 dnsns.jar
-rwxr-xr-x 1 44516 Mar 15 2017 jaccess.jar
-rwxr-xr-x 1 18490072 Mar 15 2017 jfxrt.jar
-rwxr-xr-x 1 1179093 Mar 15 2017 localedata.jar
-rwxr-xr-x 1 1269 Mar 15 2017 meta-index
-rwxr-xr-x 1 2022531 Mar 15 2017 nashorn.jar
-rwxr-xr-x 1 42154 Mar 15 2017 sunec.jar
-rwxr-xr-x 1 280161 Mar 15 2017 sunjce_provider.jar
-rwxr-xr-x 1 251327 Mar 15 2017 sunpkcs11.jar
-rwxr-xr-x 1 68924 Mar 15 2017 zipfs.jar

所以,只单单指定了额外依赖的jar包后,就会导致ext目录下的jar包无法加载,而这次我们新增的加解密模块使用了HmacSHA256算法,依赖于sunjce_provider.jar包的内容,当我们在本地环境调试时,直接IDEA启动,没有出现依赖加载错误的问题,而当在测试环境使用启动脚本启动并且指定了-Djava.ext.dirs就导致了依赖出错。

问题解决:

问题已经找出,那么解决就很简单,-Djava.ext.dirs引入多个路径加入Java自带ext路径即可

1
java  -Djava.ext.dirs=../lib:$JAVA_HOME/jre/lib/ext -jar