最近在开发过程中遇到了一个“棘手”的问题,说它棘手是因为经过了多方的排查还是定位不到问题所在,后面还是根据同事一个不经意的提醒,才搞定的。接下来还原整个问题处理的经过
一、背景描述
我是Springboot2 + JDK1.8的工程,在配置文件里面数据库连接串使用了加密的密码:
db.spring.datasource.url=jdbc:oracle:thin:@************
db.spring.datasource.username=****_adm
#db.spring.datasource.password=***_864
db.spring.datasource.password=ENC(rb5a3YJ*******cHMJ3OD)
程序正常编译通过,本地启动正常,如果使用明文密码,部署一切正常。如果是采用加密的密码,则打镜像部署到k8s容器上报下面的异常。详细报错信息如下:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
[/] 2025-02-27 17:01:17 [main] o.s.b.diagnostics.LoggingFailureAnalysisReporter -
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to bind properties under 'db.spring.datasource.password' to java.lang.String:
Reason: java.lang.NoClassDefFoundError: Could not initialize class com.ibm.icu.impl.NormalizerImpl
Action:
Update your application's configuration
二、原因分析
根据网上找的资料,以及通过大模型寻找解决方案,首先是在依赖中添加下面的依赖:
<dependency>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
<version>72.1</version> <!-- 检查最新版本 -->
</dependency>
然后剔除项目中原本有包含com.ibm.icu.impl.NormalizerImpl的依赖。
一开始找不到哪个依赖中有包含上面的包,还怀疑是升级了基础镜像的问题,后面发现和基础镜像完全没啥关系。然后就怀疑本地JDK版本和容器版本是否不一致,排查了发现两边的版本都是JDK1.8。这下又毫无头绪了……
然后问了许多同事都说不清楚,后面经一个同事的提醒,才找到那个顽固的依赖所在:
先在工程里面import报错的包,然后反向找到依赖的所在:
三、解决方案
找到依赖所在后,将该包给exclusion掉:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-app</artifactId>
<version>1.8.10</version>
<exclusions>
<exclusion>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
</exclusion>
</exclusions>
</dependency>
剔除掉重新打镜像部署,还是发现启动不起来,报同样的错。
后面发现是pdfbox-app依赖本身版本和JDK版本的冲突导致的,所以将依赖进行升级:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-app</artifactId>
<version>3.0.0</version>
</dependency>
升级完对原来引用到的代码也进行升级后,重新打包部署,成功!!!
撒花完结!