java.lang.NoSuchMethodError 之 依赖冲突解决方案

NoSuchMethodError 解决方案大全

 

问题:

本机测试环境运行无误,在服务器和别的jar包一起打包在一起运行报错,这种大概率为依赖冲突问题

java.lang.NoSuchMethodError:com.google.protobuf.CodedInputStream.readStringRequireUtf8()Ljava/lang/String

 

第一层:

--> calass类名写错了

解决方案:

修改一下submit submit脚本的类名

 

第二层:

--> 对应包未打入Jar包

解决方案:

检查mvn package打的包里有没有这个依赖或者项目,这里推荐JD-GUI,可以查看jar包中包含了哪些项目的class,如果没有打入包里,

可以查看pom文件是否加入对应依赖或者对应依赖被标记为provided而运行环境未提供该jar包

JD-GUI下载地址:http://java-decompiler.github.io/

 

第三层:

--> 如果排除前两种情况,恭喜进入第三层,jar包冲突,这是我的报错信息:

java.lang.NoSuchMethodError:com.google.protobuf.CodedInputStream.readStringRequireUtf8()Ljava/lang/String

具体的报错信息:

 

1.确定原始冲突jar包:

这里通过具体报错信息可以看到是ConfigProto类的com.google.protobuf接口出了问题,所以原始冲突jar包就是包含Configproto的maven

依赖,这里是org.tensorflow。如果对属于哪个依赖不清楚,就到项目里找import函数,看Configproto的前缀是那个依赖。

2.通过Maven依赖树寻找其他包含com.google.protobuf包的项目

mvn -Dverbose dependency:tree

在命令行输入命令可以看到maven依赖树:

可以看到搜索出来多个com.google.protobuf,报错的protobuf版本是3.x版本,可以看到搜到的很多项目中依赖为2.5.0版本,所以引发了

jar包的冲突依赖。ok,现在已经锁定了出问题的jar包就在右侧红线标亮的这些jar中,版本冲突就是3.x和2.x。接下来需要的就是逐一解

决。

3.解决冲突的依赖包

A.通过exclude即可解决的冲突

第一个冲突的地方是hadoop-client,这里hadoop环境配置的protobuf版本为2.5.0,可以增加exclude改为如下配置:

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.6.0</version>
            <scope>provided</scope>
            <exclusions>
                <exclusion>
                    <groupId>com.google.protobuf</groupId>
                    <artifactId>protobuf-java</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

B.通过shaded才能解决的冲突

第二个冲突的地方是hbase-client,这里protobuf环境同样为2.5.0

使用上面同样的exclude方法可以打包,但是运行时会导致hbase报错,因此这里还有另一种解决方法:

这里shaded考虑使用别名,类似于maven-shaded-plugin中的重命名的relocation方法一样,问题解决

        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-shaded-client</artifactId>
            <version>1.2.6</version>
        </dependency>

C.通过maven-shade-plugin才能解决的冲突

上述两种都无法解决就需要请maven插件来实现包的别名,不过在我上述场景下,这个方法无效,所以也不展开了。有兴趣的小伙伴搜一

下这个打包插件的使用,使用relocation就能给自己项目的包起别名。

                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>

 

Tips:

遇到问题不要慌,jar包冲突其实也没什么,锁定原始jar包,寻找重名类jar包,替换或排除,一会就搞定了。大不了采用暴力破解法,遍

历自己的依赖,一个一个固定变量排除法,总会解决的~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章