记一次java.lang.NoSuchMethodError: org.apache.http.conn.ssl.SSLConnectionSocketFactory报错解决
sprintboot 项目,因为项目需要上传文件至阿里云。引入了阿里云 oss 的 sdk。
<dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.10.2</version> </dependency>
项目中原来就用过阿里云 oss 的 sdk,版本较老 2.8 的版本。因为种种原因,有两年没有用过相关功能了。所以这次升级了 sdk 版本。
本来以为是个简单的功能。老版本 sdk 也是我接入的么,没啥问题。
万万没想到!!!本地 idea 里面开发跑的好好的。通过 jekins 打包发版到测试环境上 ossClient 初始化报错了!!!
报错内容:
java.lang.NoSuchMethodError: org.apache.http.conn.ssl.SSLConnectionSocketFactory.<init>(Ljavax/net/ssl/SSLContext;Ljavax/net/ssl/HostnameVerifier;)V at com.aliyun.oss.common.comm.DefaultServiceClient.createHttpClientConnectionManager(DefaultServiceClient.java:244) at com.aliyun.oss.common.comm.DefaultServiceClient.<init>(DefaultServiceClient.java:85) at com.aliyun.oss.OSSClient.<init>(OSSClient.java:209) at com.aliyun.oss.OSSClient.<init>(OSSClient.java:129)
纳尼?本地是好的呀。这是什么情况?
百度后,大部分人说是 jar 冲突了。oss 的 sdk 要求的 httpclient 的版本是 4.4.1,把版本改成 4.4.1 及以上就好了。
我们项目的 httpclient 版本就是 4.4.1。改成了 4.5.2,放在服务器上还是报错。
继续百度如何查看项目的 jar 冲突。
1. 使用 idea 自带的 Maven 工具查看项目依赖关系, 具体地址如下
https://www.jianshu.com/p/a8a77d6262ed
https://blog.csdn.net/iechenyb/article/details/76945238
2. 下载了一个 maven tree 插件,方便查看哪些 jar 有冲突。
我们项目历史悠久,添加了各种引用,很臃肿。所以冲突很多。好不容易通过 exclusions 把 httpclient 的各种冲突解决了。
<dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.10.2</version> <exclusions> <exclusion> <artifactId>httpclient</artifactId> <groupId>org.apache.httpcomponents</groupId> </exclusion> </exclusions> </dependency>
到服务器上试了一下,还是报错。这就尴尬了。
继续百度,有人说虽然本地只有新版本的的 httpclient 的 jar 包,但是服务器上项目打包里面还是有旧版本的 jar 包,删掉就好了。
费了好大的劲,去测试服务器上把项目的 jar 包当了下来,解压查看发现里面只有一个 httpclient 的 jar 包,版本号是对的。
那么,问题在哪里呢?包没问题啊!
在本地通过 java -jar xxx.jar 运行项目。ossClient 初始化报错。
难道是 jekins 打包有问题?
于是通过 idea 本地打包 mvn clean package -DskipTests
运行本地打的包,依然报错。
继续百度,看到了阿里云 oss 的常见问题:
https://help.aliyun.com/document_detail/32024.html?spm=a2c4g.11186623.6.993.7b63250beCij8A
难道不是 httpclient 的问题,会不会是 oss 引用的其他的包有问题?
把 oss 的所有引用都检查了一遍,没有冲突,没有问题。
怎么办?完全没有头绪了。使出绝招求助大佬,大佬说是 jar 包冲突了,也有可能是哪个 jar 包把 httpclient 里的方法复写掉了。
到底是哪里冲突了呢?
大佬太忙了,面试去了。
把 External Libraries 里的所有 jar 包都点开看了一遍,除了 httpclient 的 jar 包没有 org.apache.http.conn.ssl.SSLConnectionSocketFactory 文件。
不知道怎么办的时候,安卓问我们有没有引入过本地的包。回答安卓说有啊,比如说易观方舟的 sdk 就是本地包。
突然灵光一闪,易观方舟数据埋点也是需要 http 连接的么。
点开一看,果然是他!!!
他把 httpclient 的源码拉进去了,并且把 SSLConnectionSocketFactory 里的方法改了!!!
正规的 httpclient 里的方法
气坏了!!!这也太没素质了吧!!!
至此找到了问题。
耗时一天半,被易观坑了。不正规的 sdk 害人啊。
感谢大佬。