Map Hadoop映射输出IOException在将配置中定义的类的子类作为输出发出时

Map Hadoop映射输出IOException在将配置中定义的类的子类作为输出发出时,map,hadoop,subclass,ioexception,Map,Hadoop,Subclass,Ioexception,我有3个简单的课程: public abstract class Container implements WritableComparable<Container> {} //empty public class WeightedEdge extends Container { ... } public class NodeWeightContainer extends Container { ... } 但是,我收到此错误: java.io.IOException: Type

我有3个简单的课程:

public abstract class Container implements WritableComparable<Container> {} //empty
public class WeightedEdge extends Container { ... }
public class NodeWeightContainer extends Container { ... }
但是,我收到此错误:

java.io.IOException: Type mismatch in value from map: expected org.hadoop.test.data.util.Container, recieved org.hadoop.test.data.WeightedEdge
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:1018)
at org.apache.hadoop.mapred.MapTask$OldOutputCollector.collect(MapTask.java:591)
at org.hadoop.test.map.CreateGPMap.map(CreateGPMap.java:33)
at org.hadoop.test.map.CreateGPMap.map(CreateGPMap.java:19)
at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:50)
at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:435)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:371)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:210)

为什么我不能返回配置中定义的类的子类?有办法绕过它吗?问题是我的映射阶段必须发出两种不同的对象类型。

您不能返回在配置中定义的类的子类,因为Hadoop显式检查在
setMapOutputValueClass
中指定的类类型以及它从映射器接收的类型

这样做是因为它需要序列化/反序列化从映射器发出的对象。当执行反序列化时,它将创建在
setMapOutputValueClass
调用中指定的类型的新对象,然后使用WriteableComparable接口的方法用数据填充新创建的对象

为了能够发出不同的对象类型,您可以定义容器非抽象类,并将实际对象及其类型标识符放在其中


    public enum ELEM_TYPE { WE, WECONTAINER }

    public class Container implements WritableComparable<Container>
    {
        ELEM_TYPE  type; //actual element type -
                         // WeightedEdge  or NodeWeightContainer 
        object value;

        //WritableComparable implementation
        // that casts value to the appropriate type
    } 
    public class WeightedEdge { ... }
    public class NodeWeightContainer { ... }


公共枚举元素类型{WE,WECONTAINER}
公共类容器实现了WritableComparable
{
元素类型;//实际元素类型-
//权重边或节点权重容器
目标价值;
//可写可比实现
//将值强制转换为适当的类型
} 
公共类权重边沿{…}
公共类NodeWightContainer{…}

无法返回配置中定义的类的子类,因为Hadoop会显式检查在
setMapOutputValueClass
中指定的类类型及其从映射程序接收的类型

这样做是因为它需要序列化/反序列化从映射器发出的对象。当执行反序列化时,它将创建在
setMapOutputValueClass
调用中指定的类型的新对象,然后使用WriteableComparable接口的方法用数据填充新创建的对象

为了能够发出不同的对象类型,您可以定义容器非抽象类,并将实际对象及其类型标识符放在其中


    public enum ELEM_TYPE { WE, WECONTAINER }

    public class Container implements WritableComparable<Container>
    {
        ELEM_TYPE  type; //actual element type -
                         // WeightedEdge  or NodeWeightContainer 
        object value;

        //WritableComparable implementation
        // that casts value to the appropriate type
    } 
    public class WeightedEdge { ... }
    public class NodeWeightContainer { ... }


公共枚举元素类型{WE,WECONTAINER}
公共类容器实现了WritableComparable
{
元素类型;//实际元素类型-
//权重边或节点权重容器
目标价值;
//可写可比实现
//将值强制转换为适当的类型
} 
公共类权重边沿{…}
公共类NodeWightContainer{…}

我今天也遇到了同样的问题。有一个
writeable
org.apache.hadoop.io.genericwriteable
,可以用来解决这个问题。您需要扩展该类并实现一个抽象方法:

public class Container extends GenericWritable {

    private static Class[] CLASSES = {
           WeightedEdge.class, 
           NodeWeightContainer.class,
    };

    protected Class[] getTypes() {
       return CLASSES;
    }

}

public class WeightedEdge implemets Writable {...}
public class NodeWeightContainer implements Writable {...}
现在可以使用类
容器
作为映射器的输出值类型


重要提示:您的实际地图输出类(
WeightedEdge
nodeweightcainer
)必须实现
可写
接口。

我今天也遇到了同样的问题。有一个
writeable
org.apache.hadoop.io.genericwriteable
,可以用来解决这个问题。您需要扩展该类并实现一个抽象方法:

public class Container extends GenericWritable {

    private static Class[] CLASSES = {
           WeightedEdge.class, 
           NodeWeightContainer.class,
    };

    protected Class[] getTypes() {
       return CLASSES;
    }

}

public class WeightedEdge implemets Writable {...}
public class NodeWeightContainer implements Writable {...}
现在可以使用类
容器
作为映射器的输出值类型

重要提示:实际地图输出类(
WeightedEdge
nodeweightcainer
)必须实现
可写
接口