记一个 protobuf 的 jar 包冲突

尝试使用 spark 以 bulkload 的方式写 HBase 时,遇到一个问题,错误堆栈如下

19/02/02 09:00:43 ERROR Utils: Aborting task
java.lang.NoSuchMethodError: org.apache.hadoop.hbase.util.ByteStringer.wrap([B)L/com/google/protobuf/ByteString;
	at org.apache.hadoop.hbase.io.hfile.HFile$FileInfo.write(HFile.java:709)
	at org.apache.hadoop.hbase.io.hfile.AbstractHFileWriter.writeFileInfo(AbstractHFileWriter.java:184)
	at org.apache.hadoop.hbase.io.hfile.HFileWriterV2.close(HFileWriterV2.java:346)
	at org.apache.hadoop.hbase.regionserver.StoreFile$Writer.close(StoreFile.java:996)
	at org.apache.hadoop.hbase.mapreduce.HFileOutputFormat2$1.close(HFileOutputFormat2.java:269)
	at org.apache.hadoop.hbase.mapreduce.HFileOutputFormat2$1.close(HFileOutputFormat2.java:277)
	at org.apache.spark.internal.io.HadoopMapReduceWriteConfigUtil.closeWriter(SparkHadoopWriter.scala:357)
	at org.apache.spark.internal.io.SparkHadoopWriter$$anonfun$4.apply(SparkHadoopWriter.scala:133)
	at org.apache.spark.internal.io.SparkHadoopWriter$$anonfun$4.apply(SparkHadoopWriter.scala:123)
	at org.apache.spark.util.Utils$.tryWithSafeFinallyAndFailureCallbacks(Utils.scala:1414)
	at org.apache.spark.internal.io.SparkHadoopWriter$.org$apache$spark$internal$io$SparkHadoopWriter$$executeTask(SparkHadoopWriter.scala:135)
	at org.apache.spark.internal.io.SparkHadoopWriter$$anonfun$3.apply(SparkHadoopWriter.scala:79)
	at org.apache.spark.internal.io.SparkHadoopWriter$$anonfun$3.apply(SparkHadoopWriter.scala:78)
	at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:87)
	at org.apache.spark.scheduler.Task.run(Task.scala:109)
	at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:345)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

一开始以为是找不到 com.google.protobuf.ByteString,怎么都没想明白。后来找同事讨论,确定问题是找不到 return 为 com.google.protobuf.ByteString 的 org.apache.hadoop.hbase.util.ByteStringer.wrap 的函数

 

原因如下:

同时引用了 org.apache.hbase:hbase-shaded-client 和 org.apache.hbase:hbase-protocol,其中都有类 org.apache.hadoop.hbase.util.ByteStringer 和 方法 wrap,但是返回值分别为 org.apache.hadoop.hbase.shaded.com.google.protobuf.ByteString 和 com.google.protobuf.ByteString。前者被打进 jar 包,于是有了之前的错误。

更进一步,发生这个错误的原因,是在引用 hbase 依赖的时候,同时引用了 shaded 和非 shaded,这是错误的。于是改成都使用 shaded 的 hbase 依赖。

posted @ 2019-02-02 20:26  徐软件  阅读(2488)  评论(0编辑  收藏  举报