问题背景
SprintBoot项目使用Okhttp 封装SDK common-http,根据官网使用Maven导入JavaSDK
<dependency>
<groupId>io.github.admin4j</groupId>
<artifactId>http</artifactId>
<version>0.7.4</version>
</dependency>
运行报错:
java.lang.NoClassDefFoundError: okio.Buffer
at okhttp3.ResponseBody$Companion.create(ResponseBody.kt:248)
at okhttp3.ResponseBody$Companion.create$default(ResponseBody.kt:247)
at okhttp3.internal.Util.<clinit>(Util.kt:65)
at okhttp3.HttpUrl$Builder.parse$okhttp(HttpUrl.kt:1239)
at okhttp3.HttpUrl$Companion.get(HttpUrl.kt:1634)
at okhttp3.Request$Builder.url(Request.kt:184)
at io.github.admin4j.http.core.AbstractHttpBuildCall.buildRequest(AbstractHttpBuildCall.java:182)
at io.github.admin4j.http.core.AbstractHttpBuildCall.buildPost(AbstractHttpBuildCall.java:410)
at io.github.admin4j.http.core.AbstractHttpRequest.post(AbstractHttpRequest.java:59)
解决过程
-
排查
http
的Maven包的依赖发现是依赖了okhttp 4.11.0,但是器依赖的
okio
却是3.0.0
。而okhttp 4.11.0 是需要依赖 okio 3.2.0 这就是okhttp包发生了依赖冲突。 -
分析项目对okhttp依赖
项目是一个Maven多模块的项目,排查了父包、公共包和出错的子包之后发现只有http
依赖了Okhttp。这就很迷惑了,为什么明明依赖的版本是4.110,但是排查出来的依赖版本变成了3.14.9。 -
尝试排除依赖重新指定
<dependency> <groupId>io.github.admin4j</groupId> <artifactId>http</artifactId> <version>0.7.3</version> <exclusions> <exclusion> <artifactId>okhttp</artifactId> <groupId>com.squareup.okhttp3</groupId> </exclusion> </exclusions> </dependency> <dependency> <artifactId>okhttp</artifactId> <groupId>com.squareup.okhttp3</groupId> <version>4.11.0</version> </dependency>
如上修改后,明确指定了OkHttp版本的Maven项目还是运行失败,出现原来的错误,但是依赖该Maven项目的其他子项目依旧okio版本为3.0.0。这不就是灵异事件嘛!
-
灵光一现
突然发现指定okhttp依赖时左边IDEA提示了是继承的,即有包指定了Okhttp的版本。点进去一看,好家伙SprintBoot依赖包(父工程)中指定了okio版本,版本号就是3.0.0。而我的项目的根项目就指定了SpringBoot的版本,子项目中使用了SpringBoot!了解了一下,Maven包如果存在依赖管理(dependencyManagement)那么该模块的子模块和依赖包中的相关包都将自动使用这个版本,而且子模块可以覆盖、依赖包中的依赖管理会被引用者覆盖。dependencyManagement 优先级优先于传递依赖
解决方案
在根模块的POM中添加dependencyManagement,这样会覆盖掉父工程指定的依赖版本。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>3.2.0</version>
</dependency>
</dependencies>
</dependencyManagement>
或者直接依赖于
<dependencies>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>3.2.0</version>
</dependency>
</dependencies>