记录Maven 依赖包版本号奇奇怪怪的问题 - okhttp3、okio 版本指定无效

问题背景

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)

解决过程

  1. 排查http的Maven包的依赖

    image-20230705111311634

    发现是依赖了okhttp 4.11.0,但是器依赖的 okio 却是 3.0.0 。而okhttp 4.11.0 是需要依赖 okio 3.2.0 这就是okhttp包发生了依赖冲突。

  2. 分析项目对okhttp依赖
    image-20230705111527591
    项目是一个Maven多模块的项目,排查了父包、公共包和出错的子包之后发现只有http依赖了Okhttp。这就很迷惑了,为什么明明依赖的版本是4.110,但是排查出来的依赖版本变成了3.14.9。

  3. 尝试排除依赖重新指定

          <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。这不就是灵异事件嘛!

    image-20230705111752295

  4. 灵光一现
    突然发现指定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>

猜你喜欢

转载自blog.csdn.net/agonie201218/article/details/131552134