使用 spark 读取 avro 数据并得到 org.apache.avro.util.Utf8 cannot be cast to java.lang.String Exception
use spark to read avro data and got org.apache.avro.util.Utf8 cannot be cast to java.lang.String Exception
我正在使用以下代码在 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()
以使其工作,但是因为我在另一个 hadoop mapreduce 作业中使用它很好,我希望所有的 utf8 都可以自动转换为字符串,以便我不需要更改所有代码逻辑。
综上所述,如何让GenericRecord
中的org.apache.avro.util.Utf8
全部自动转为java.lang.String
?
看起来解决方案是使用 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") });
我正在使用以下代码在 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()
以使其工作,但是因为我在另一个 hadoop mapreduce 作业中使用它很好,我希望所有的 utf8 都可以自动转换为字符串,以便我不需要更改所有代码逻辑。
综上所述,如何让GenericRecord
中的org.apache.avro.util.Utf8
全部自动转为java.lang.String
?
看起来解决方案是使用 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") });