总之岁月漫长,然而值得等待。
主要是版本冲突问题,具体报错与解决方法如下:
报错前:
启动失败
短信服务测试报错:
解决后:
启动成功
短信服务测试发送成功:
在使用 SpringBoot 开发时,我们经常会引入各种依赖以满足功能需求。然而,依赖版本不一致的问题可能会导致一些复杂的错误。最近在项目中,我遇到了一个典型的 NoClassDefFoundError 问题,经过排查发现其根本原因是依赖版本冲突。
一、问题描述
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2024-11-29 00:53:51.262 INFO 19140 --- [ main] c.a.alicloud.oss.OssApplicationListener : 0 OSSClients will be shutdown soon
2024-11-29 00:53:51.278 ERROR 19140 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'OSSController': Unsatisfied dependency expressed through field 'ossClient'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ossClient' defined in class path resource [com/alibaba/alicloud/context/oss/OssContextAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.aliyun.oss.OSS]: Factory method 'ossClient' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/http/ssl/SSLContextBuilder
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:659) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:639) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.12.jar:5.3.12]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.12.jar:5.3.12]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.12.jar:5.3.12]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.12.jar:2.4.12]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:771) [spring-boot-2.4.12.jar:2.4.12]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:763) [spring-boot-2.4.12.jar:2.4.12]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:438) [spring-boot-2.4.12.jar:2.4.12]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:339) [spring-boot-2.4.12.jar:2.4.12]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1329) [spring-boot-2.4.12.jar:2.4.12]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1318) [spring-boot-2.4.12.jar:2.4.12]
at com.chhei.mall.third.MallThirdPartyApplication.main(MallThirdPartyApplication.java:12) [classes/:na]
Caused by: java.lang.NoClassDefFoundError: org/apache/http/ssl/SSLContextBuilder
详细堆栈信息提示 SSLContextBuilder 类无法被加载,而该类属于 Apache 的 httpclient 包。在分析日志后,定位到问题是阿里云 OSS 客户端(com.aliyun.oss.OSS)在初始化时无法正确加载 org.apache.http.ssl.SSLContextBuilder 类。
二、问题分析
1.定位问题依赖 报错中提到的 SSLContextBuilder 位于 org.apache.httpcomponents 的 httpclient 包中。通过查看 Maven 仓库可知,它需要以下两个核心依赖:
httpclient
httpcore
2.版本冲突 项目中直接或间接引入了多个版本的 httpcore,分别是:
通用工具类:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.14</version>
</dependency>
第三方服务类:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.1</version>
</dependency>
这两个依赖版本要统一或接近,统一完后就不报错了,具体统一可以直接改成一模一样的版本,子 类pom像父类看齐,也可以参考一下其他方法。
三、解决方案(其他)
排除冲突依赖 对于引入旧版本 httpcore 的依赖,通过排除方式在子类pom文件中移除冲突版本:
<dependency>
<groupId>某依赖的groupId</groupId>
<artifactId>某依赖的artifactId</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
</exclusion>
</exclusions>
</dependency>
再引入自己独立的版本:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.2.1</version>
</dependency>
版本不要相差太大一般不会有什么问题。
最后终端进入对应的第三方模块输入:
mvn clean install