使用spark读取avro数据并获取org.apache.avro.util.utf8无法转换为java.lang.string异常

h7appiyu  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(1756)

我使用以下代码来读取spark中的avro:

val inputData = sc.hadoopFile(inputPath,
  classOf[AvroInputFormat[GenericRecord]],
  classOf[AvroWrapper[GenericRecord]]).map(t => 
{ val genericRecord = t._1.datum()  
(String)genericRecord.get("name") });

加载部分工作正常,但转换为字符串部分失败:

Caused by: java.lang.ClassCastException: org.apache.avro.util.Utf8 cannot be cast to java.lang.String

为了简化这个例子,我使用了一条线

(String)genericRecord.get("name")

实际上,该部分来自一个库,在hadoop map reduce作业中可以很好地使用。但是,当我现在在spark中使用该库时,由于上述异常,它失败了。
我知道我可以把密码改成 genericRecord.get("name").toString() 但由于我在另一个hadoopmapreduce工作中使用得很好,我希望所有的utf8都能自动转换成字符串,这样我就不需要更改所有的代码逻辑。
总之,如何使所有的 org.apache.avro.util.Utf8GenericRecord 自动转换为 java.lang.String ?

jmo0nnb3

jmo0nnb31#

看来解决办法是 AvroKey 而不是 AvroWrapper . 下面的代码工作,所有的 org.apache.avro.util.Utf8 将自动转换为 java.lang.String . 再也不例外了。

val inputData = sc.newAPIHadoopFile(inputPath,
classOf[AvroKeyInputFormat[GenericRecord]],
classOf[AvroKey[GenericRecord]],
classOf[NullWritable]).map(t => 
{ val genericRecord = t._1.datum()  
(String)genericRecord.get("name") });

相关问题