工程启动报java.lang.NoClassDefFoundError错,解决!

最近在开发过程中遇到了一个“棘手”的问题,说它棘手是因为经过了多方的排查还是定位不到问题所在,后面还是根据同事一个不经意的提醒,才搞定的。接下来还原整个问题处理的经过

一、背景描述
我是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>

升级完对原来引用到的代码也进行升级后,重新打包部署,成功!!!

撒花完结!

### 关于 `java.lang.NoClassDefFoundError: DefaultDingTalkClient` 的解决方案 `java.lang.NoClassDefFoundError` 表示在 Java 应用程序运行期间,JVM 尝试加载指定的类(在此情况下为 `DefaultDingTalkClient`),但由于某些原因未能成功定位到该类的 `.class` 文件[^1]。 此问题可能由以下几个常见原因引起: 1. **缺少必要的依赖项** 如果项目中未引入包含 `DefaultDingTalkClient` 类的相关 JAR 包或 Maven/Gradle 依赖,则会在运行时引发此类误。这通常是由于构建工具配置不当造成的[^2]。 2. **类路径设置不正确** 即使所需的 JAR 已存在于项目的构建环境中,在部署阶段如果没有将其正确添加至运行时类路径中,也会触发 `NoClassDefFoundError` 误[^3]。 3. **版本冲突** 当多个不同版本的库被同时加载时,可能会导致 JVM 加载了一个不符合预期 API 定义的类实例,进而抛出异常[^4]。 #### 解决方案 以下是针对上述情况的具体处理措施: - **确认依赖是否存在并正确导入** 需要检查是否已经通过 Maven 或 Gradle 正确声明了 DingTalk SDK 所需的依赖关系。对于 Maven 用户来说,应该确保 pom.xml 中包含了类似以下的内容: ```xml <dependency> <groupId>com.dingtalk</groupId> <artifactId>dingtalk-sdk</artifactId> <version>最新稳定版号</version> </dependency> ``` - **验证运行环境中的类路径** 在启动应用程序之前,请仔细核对命令行参数或者容器配置文件里是否有遗漏任何必需 jar 文件的位置信息。例如,当使用 WebLogic Server 作为应用服务器时,可以借助 `-cp` 参数手动指定额外资源目录[^5]。 - **排查第三方库之间的兼容性问题** 利用工具如 `mvn dependency:tree` 来分析整个工程内的所有间接引用及其相互作用状况;必要时候升级基础框架直至消除潜在矛盾点为止。 最后附上一段修正后的代码片段供参考: ```java import com.taobao.api.DefaultTaobaoClient; // 假设此处存在其他相关 import... public class Main { public static void main(String[] args) throws Exception{ String url = "https://oapi.dingtalk.com"; String token = "your_access_token_here"; try { DefaultDingTalkClient client = new DefaultDingTalkClient(url); // 继续执行业务逻辑... } catch (Exception e){ System.err.println("初始化失败:" + e.getMessage()); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值