具有常用功能的Google Cloud Dataflow自定义密钥

时间:2015-12-03 03:06:03

标签: google-cloud-dataflow

我们正在使用Dataflow Java SDK,并且我们有越来越多的自定义密钥类几乎相同。

我想让它们扩展一个公共抽象类,但是Dataflow SDK似乎试图实例化导致InstantiationException的抽象类。

Caused by: java.lang.RuntimeException: java.lang.InstantiationException
    at org.apache.avro.specific.SpecificData.newInstance(SpecificData.java:316)
    at org.apache.avro.specific.SpecificData.newRecord(SpecificData.java:332)
    at org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:173)
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:151)
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:142)
    at com.google.cloud.dataflow.sdk.coders.AvroCoder.decode(AvroCoder.java:242)
    at com.google.cloud.dataflow.sdk.coders.KvCoder.decode(KvCoder.java:97)
    at com.google.cloud.dataflow.sdk.coders.KvCoder.decode(KvCoder.java:42)
    at com.google.cloud.dataflow.sdk.util.CoderUtils.decodeFromSafeStream(CoderUtils.java:156)
    at com.google.cloud.dataflow.sdk.util.CoderUtils.decodeFromByteArray(CoderUtils.java:139)
    at com.google.cloud.dataflow.sdk.util.CoderUtils.decodeFromByteArray(CoderUtils.java:133)
    at com.google.cloud.dataflow.sdk.util.MutationDetectors$CodedValueMutationDetector.<init>(MutationDetectors.java:108)
    at com.google.cloud.dataflow.sdk.util.MutationDetectors.forValueWithCoder(MutationDetectors.java:45)
    at com.google.cloud.dataflow.sdk.transforms.ParDo$ImmutabilityCheckingOutputManager.output(ParDo.java:1218)
    at com.google.cloud.dataflow.sdk.util.DoFnRunner$DoFnContext.outputWindowedValue(DoFnRunner.java:329)
    at com.google.cloud.dataflow.sdk.util.DoFnRunner$DoFnProcessContext.output(DoFnRunner.java:483)
    at com.telstra.cdf.rmr.model.pardos.ParDoAbstractCampaignUAKeyExtractor.processElement(ParDoAbstractCampaignUAKeyExtractor.java:5

这是我们的抽象类,

@DefaultCoder(AvroCoder.class)
public abstract class SuperClassKey  {
    public SuperClassKey(){}
    public abstract double getSomeValue();
}

这是子类

@DefaultCoder(AvroCoder.class)
public class SubClassKey extends SuperClassKey {
    public String foo;

    public SubClassKey() {
    }

    public SubClassKey(String foo){
        this.foo = foo;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        SubClassKey that = (SubClassKey) o;

        if (!foo.equals(that.foo)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return foo.hashCode();
    }

    @Override
    public double getSomeValue() {
        return foo;
    }
}

我也试过使用界面但没有成功。

键之间是否可以有一个共同的抽象类或接口?

2 个答案:

答案 0 :(得分:2)

问题可能来自使用PCollection<SuperClassKey>而不是PCollection<SubClassKey>。 PCollection需要使用具体类进行输入。如果类型推断不充分,则可以使用.setCoder(AvroCoder.of(SubClassKey.class))显式指定编码器。

答案 1 :(得分:0)

在我的Canse中,我更改了Coder类,例如:

之前:

AvroIO.parseGenericRecords(RecordConverter::convert)
 .withCoder(AvroCoder.of(Struct.class)).from(...)

之后:

AvroIO.parseGenericRecords(RecordConverter::convert)
 .withCoder(SerializableCoder.of(Struct.class)).from(...)