Jar包冲突问题的排查和解决

出现问题

在一次需求迭代中,只是改了某个接口的内容,但在预发环境构建之后居然发现调用接口出现java.lang.NoSuchMethodError: kotlin.collections.ArraysKt.copyInto([B[BIII)[B 的错误。

查找原因

通过查找日志发现,这是我使用的forest网络框架提示出来的,如下:

java.lang.NoSuchMethodError: kotlin.collections.ArraysKt.copyInto([B[BIII)[B
    at okio.Buffer.write(Buffer.kt:1640)
    at okio.RealBufferedSink.write(RealBufferedSink.kt:174)
    at okhttp3.RequestBody$2.writeTo(RequestBody.java:98)
    at com.dtflys.forest.backend.okhttp3.logging.OkHttp3LogBodyMessage.getLogContentForStringBody(OkHttp3LogBodyMessage.java:42)
    at com.dtflys.forest.backend.okhttp3.logging.OkHttp3LogBodyMessage.getBodyString(OkHttp3LogBodyMessage.java:141)
    at com.dtflys.forest.logging.DefaultLogHandler.requestLoggingBody(DefaultLogHandler.java:51)
    at com.dtflys.forest.logging.DefaultLogHandler.requestLoggingContent(DefaultLogHandler.java:117)
    at com.dtflys.forest.logging.DefaultLogHandler.logRequest(DefaultLogHandler.java:169)
    at com.dtflys.forest.backend.okhttp3.executor.AbstractOkHttp3Executor.logRequest(AbstractOkHttp3Executor.java:110)
    at com.dtflys.forest.backend.okhttp3.executor.AbstractOkHttp3Executor.execute(AbstractOkHttp3Executor.java:187)
    at com.dtflys.forest.backend.okhttp3.executor.AbstractOkHttp3Executor.execute(AbstractOkHttp3Executor.java:288)
    at com.dtflys.forest.http.ForestRequest.execute(ForestRequest.java:1687)
    at com.dtflys.forest.http.ForestRequest.execute(ForestRequest.java:1704)
    at com.dtflys.forest.reflection.ForestMethod.invoke(ForestMethod.java:1175)
    at com.dtflys.forest.proxy.InterfaceProxyHandler.invoke(InterfaceProxyHandler.java:126)
    at com.sun.proxy.$Proxy174.createYonYouOrder(Unknown Source)

请教了一下forest的作者,告诉我这应该是okio和okhttp的包冲突导致的,其实事后详细从上面的日志也不难看出来。

可是我百思不得其解,我并没有更新pom文件,也就是并没有引入新的包进来,理论上应该还是和上一个版本一样的,但上一个版本是正常的,虽然很难理解,但我还是去对比正式环境和预发布环境看看这两个jar分别是什么版本的。

进入容器可使用以下命令查看引用的依赖jar的版本,当然其实如果你把应用jar包解压出来去看也是可以的。

jar tf app.jar |grep okio
jar tf app.jar |grep okhttp

这里发现正式环境和预发环境的okhttp的版本是一样的,但okio的版本不一样,预发的是2.7.0,而正式的则是1.50.0。

这还真奇了怪了,没有更新maven依赖怎么会导致这样的结果呢,于是我在idea里面去查找okio这个依赖。

idea查找依赖的关系和版本

Jar包冲突问题的排查和解决_第1张图片

在pom.xml文件里面右键Maven→Show Dependencies... 或者使用快捷键Ctrl+Alt+Shift+U,会生成maven依赖关系图。

然后Ctrl+F查找okio.

Jar包冲突问题的排查和解决_第2张图片

 确实有两个,逐个去看了,那个高版本的是华为云的一个包依赖的。

Jar包冲突问题的排查和解决_第3张图片

 然后我去看了下pom里面那个依赖引入是这样写的:


    com.huaweicloud
    esdk-obs-java
    [3.19.7,)

这里的version指定的是[3.19.7,),意思是版本>=3.19.7,并取最新的发布版本,所以导致预发重新构建出来的版本不一样了,我再次去预发和正式环境查看了一下这个包的版本,确实是这样的。正式esdk-obs-java版本是3.21.4.1而预发是3.21.8。

解决方案

原因找到了,解决也就容易了。有两个办法,一是固定esdk-obs-java版本为3.21.4.1,二是升级okhttp版本使得和okio版本对应。

这里选择了第一个办法,因为可快速解决,并且升级okhttp也担心会有其他问题,还需要测试验证。

你可能感兴趣的:(程序员日常,Java,java)