将第三方类扩展为Hadoop可写入代理

时间:2012-03-29 01:26:09

标签: java serialization hadoop proxy-classes writable

我有一个我想在Hadoop中使用的第三方类,因此需要让它实现Writable。问题是Hadoop使用Writable的方式是创建一个对象o = SomeObject(),然后调用o.readFields(in)来反序列化,在我的情况下我不能创建空对象:

public abstract class Cube {
    protected final int size;
    protected Cube(int size) { this.size = size; }
}

注意sizefinal

public class RealCube {
    public Cube(int size) { super(size); }
}

这里RealCube只有一个超级构造函数要调用,而construtor在抽象超类中设置final变量。

public class RealCubeWritable implements Writable {
    public void readFields(DataInput in) {
        /* yikes! need to set the size */
    }
}

当我们开始尝试实施RealCubeWritable时,我无法拥有RealCubeWritable()构造函数,并且在检查size流之前我无法知道实际的DataInput

因此,似乎在Hadoop中执行此操作的唯一方法是使用包装器。我想知道的是,是否有办法使用包装器,但RealCubeWritable仍然表现得像RealCube?我已经研究过使用动态代理类,但我不确定这是否可行(或者如何实际执行)。

谢谢!

1 个答案:

答案 0 :(得分:1)

如果你真的无法控制Cube对象,那么我不确定你有很多(愉快的)选择:

  • 我不确定我理解你的包装器或代理对象是什么意思 - 无论是final是最终的,所以你需要创建一个没有最终标志的类的副本
  • 您可能可以使用讨厌的反射黑客来允许您取消大小字段,然后通过反射设置字段值,但如果Cube初始化了其他变量,则可能会导致一些未定义的行为。构造
  • 您可以编写自己的Serialization类,这将允许您为每个对象创建一个新的RealCube实例(不是最有效的,但它会起作用)(而不是利用传统的hadoop对象重用)< / LI>
  • size的域名是否相对较小? (即它只能是有限的一组/值范围)。如果是这样,您可以为每个有效大小值创建RealCube实例,并再次使用自定义序列化实现,根据从输入流中读取的大小选择正确的Cube实例