Hadoop序列化嵌套对象

时间:2012-09-16 11:52:14

标签: java serialization hadoop writable

我有一个班级:

 class Class1 implements Writable{
       int intField;
       double doubleField;
       Class2 refToClass2;

       public void readField(DataInput in){...}
       public void write(DataOutput out){...}


 class Class2 implements Serializable, Writable{
     ....
 }

当使用Class1作为输出值时,Hadoop会在reducer端抛出此错误:

 java.lang.NullPointerException
at org.apache.hadoop.io.serializer.SerializationFactory.getSerializer(SerializationFactory.java:73)
at org.apache.hadoop.io.SequenceFile$Writer.init(SequenceFile.java:961)
at org.apache.hadoop.io.SequenceFile$Writer.<init>(SequenceFile.java:892)
at org.apache.hadoop.io.SequenceFile.createWriter(SequenceFile.java:393)
at org.apache.hadoop.io.SequenceFile.createWriter(SequenceFile.java:354)
at org.apache.hadoop.io.SequenceFile.createWriter(SequenceFile.java:476)
at org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat.getRecordWriter(SequenceFileOutputFormat.java:61)
at org.apache.hadoop.mapred.ReduceTask$NewTrackingRecordWriter.<init>(ReduceTask.java:569)

我的直觉告诉我,问题与Class1或更多可能与Class2相关,Class2实现Serializable和Writable。

有什么想法吗?

更新

我对问题进行了本地化:问题是Class1,现在,我已经改为仅实现Writable(也不是Serializable)。我也改变了它,因为它不再包含对Class2的引用。我仍然得到同样的错误。如果我将Class1替换为另一个Writable实现作为输出值,它可以工作! 为什么??

1 个答案:

答案 0 :(得分:1)

问题在于我犯了一个愚蠢的错误:我没有更新罐子。因此,基本上Class1没有在旧的(使用中)jar中实现Writable接口。

作为一般观察:OP中指定的错误具有潜在原因,HADOOP无法为您尝试序列化的特定类型(直接或间接地,例如通过使用该类型)找到序列化程序作为输出键/值)。由于以下两个原因之一,Hadoop无法找到Serilizer:

  1. 您的类型不可序列化(即它不实现Writable或Serializable)
  2. Hadoop没有可用于您的类型实现的序列化类型的序列化程序(例如:您的类型实现Writable但hadoop因某种原因无法使用org.apache.hadoop.io.serializer.WritableSerialization类)