cqc3073
1/2/2018 - 8:06 AM

java版本版本冲突的识别

java版本版本冲突的识别

先划重点

想看哪个类是从哪个包中加载出来,可在java 启动参数加添加-verbose:class, 这样在应用启动的时候会把所有的类加载路径给打印出来

背景

随着现在的应用集成的库越来越多,一不小心就出现了版本兼容的问题,特别是这种问题是时好时坏

最近在调研 tez on hive 的功能,发现相同的语句有时候执行成功,有时候又执行失败,查了下失败任务的日志,报了这个错:

Caused by: java.lang.NoSuchMethodError: org.apache.tez.mapreduce.protos.MRRuntimeProtos$MRInputUserPayloadProto.getConfigurationBytes()Lorg/spark-project/hive/shaded/com/google/protobuf/ByteString;   
     at org.apache.hadoop.hive.ql.exec.tez.HiveSplitGenerator.(HiveSplitGenerator.java:94)   ... 30 more

这第一直觉就是包的版本有问题,查了下这个类所在的包 tez-mapreduce-0.8.4.jar, 有这个类也有这个方法呀,怎么就有问题呢?由于任务的执行是分布式的,通过调试比较困难,期间也是采用了不少方法去定位问题,后来考虑把所有类的加载路径给打印出来,在java任务启动的时候加上这个参数 -verbose:class, 那么任务启动后会打印出加载信息

...
[Loaded org.apache.hadoop.mapred.InputFormat from file:/mnt/disk1/yarn/usercache/anonymous/filecache/88/spark-assembly-1.6.1-hadoop2.7.2.jar]
[Loaded org.apache.tez.mapreduce.protos.MRRuntimeProtos$MRInputUserPayloadProtoOrBuilder from file:/mnt/disk1/yarn/filecache/91/tez-mapreduce-0.8.4.jar]
[Loaded org.apache.tez.mapreduce.protos.MRRuntimeProtos$MRInputUserPayloadProto from file:/mnt/disk1/yarn/filecache/91/tez-mapreduce-0.8.4.jar]
[Loaded org.apache.tez.mapreduce.protos.MRRuntimeProtos$MRSplitsProtoOrBuilder from file:/mnt/disk1/yarn/filecache/91/tez-mapreduce-0.8.4.jar]
[Loaded org.apache.tez.mapreduce.protos.MRRuntimeProtos$MRInputUserPayloadProto$1 from file:/mnt/disk1/yarn/filecache/91/tez-mapreduce-0.8.4.jar]
[Loaded org.apache.tez.mapreduce.protos.MRRuntimeProtos$MRSplitsProto from file:/mnt/disk1/yarn/filecache/91/tez-mapreduce-0.8.4.jar]
[Loaded org.apache.tez.mapreduce.protos.MRRuntimeProtos$MRSplitsProto$1 from
... 

[Loaded org.apache.tez.mapreduce.protos.MRRuntimeProtos$MRInputUserPayloadProto from file:/mnt/disk1/yarn/filecache/91/tez-mapreduce-0.8.4.jar] 是从我预期的包加载出来的, 那怀疑是调用的类有问题,再查下HiveSplitGenerator的出处

[Loaded org.apache.hadoop.hive.ql.exec.tez.HiveSplitGenerator from file:/mnt/disk1/yarn/usercache/anonymous/filecache/88/spark-assembly-1.6.1-hadoop2.7.2.jar]

问题基本定位了,包不符合我的预期,我预期应该是hive-exec-2.0.0.jar

问题找到就好办了,解决方法就是把两个有冲突的包给去掉一个或合并,要结合业务需要,也许两个包其中的部分是业务需要的。(虽然思路很简单,但有些大的框架过于复杂,连有些包是怎么加载进来的都排查的不轻松,这个案例中spark-assembly-1.6.1-hadoop2.7.2.jar这个包也是费了很大的劲才查出来)