微服务之短信验证服务配置完后junit单元测试短信发送失败

总之岁月漫长,然而值得等待。

主要是版本冲突问题,具体报错与解决方法如下:

报错前:
启动失败

短信服务测试报错:

解决后:
启动成功

短信服务测试发送成功:

在使用 SpringBoot 开发时,我们经常会引入各种依赖以满足功能需求。然而,依赖版本不一致的问题可能会导致一些复杂的错误。最近在项目中,我遇到了一个典型的 NoClassDefFoundError 问题,经过排查发现其根本原因是依赖版本冲突。

一、问题描述

bash 复制代码
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]
bash 复制代码
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,分别是:
通用工具类:

bash 复制代码
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
    <version>4.4.14</version>
</dependency>

第三方服务类:

bash 复制代码
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.2.1</version>
</dependency>

这两个依赖版本要统一或接近,统一完后就不报错了,具体统一可以直接改成一模一样的版本,子 类pom像父类看齐,也可以参考一下其他方法。

三、解决方案(其他)

排除冲突依赖 对于引入旧版本 httpcore 的依赖,通过排除方式在子类pom文件中移除冲突版本:

bash 复制代码
<dependency>
    <groupId>某依赖的groupId</groupId>
    <artifactId>某依赖的artifactId</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
        </exclusion>
    </exclusions>
</dependency>

再引入自己独立的版本:

bash 复制代码
<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>

版本不要相差太大一般不会有什么问题。

最后终端进入对应的第三方模块输入:

bash 复制代码
mvn clean install
相关推荐
海绵波波1073 小时前
GoogleTest做单元测试
单元测试
真上帝的左手4 小时前
架构-微服务-服务配置
分布式·微服务·云原生·中间件·架构
BestandW1shEs5 小时前
彻底理解微服务配置中心的作用
java·微服务·架构
运维&陈同学14 小时前
【微服务】消息队列与微服务之微服务详解
linux·spring boot·spring cloud·微服务·云原生·架构·云计算
sg_knight15 小时前
RabbitMQ的预取值详解
java·分布式·微服务·消息队列·rabbitmq
yours_Gabriel17 小时前
【微服务】Nacos配置管理
java·后端·微服务·架构
wenyue112119 小时前
微服务编排和调度
微服务·云原生·架构
yours_Gabriel19 小时前
【微服务】http客户端Feign
http·微服务·架构
真上帝的左手1 天前
架构-微服务-服务治理
分布式·微服务·云原生·中间件·架构·服务发现