У меня есть преобразование, которое выводит тип с подстановочным знаком: Feature<? extends Geomery>
. Я указал кодер для этого класса и создал конвейер.
final Pipeline pipeline = Pipeline.create();
final TypeDescriptor<Feature<? extends Geometry>> featureTypeDescriptor =
new TypeDescriptor<Feature<? extends Geometry>>() {
};
pipeline.getCoderRegistry().registerCoderForType(featureTypeDescriptor, FeatureCoder.of());
final List<String> data = Arrays.asList("a", "b");
final PCollection<Feature<? extends Geometry>> features =
pipeline.apply(Create.of(data).withCoder(StringUtf8Coder.of()))
.apply(ParDo.of(new DoFn<String, Feature<? extends Geometry>>() {
@ProcessElement
public void process(ProcessContext processContext) {
final String name = processContext.element();
processContext.output(new FeatureImpl(name));
}
}));
pipeline.run().waitUntilFinish();
Когда я запускаю этот конвейер, я получаю следующую ошибку:
Exception in thread "main" java.lang.ClassCastException: org.apache.beam.sdk.repackaged.com.google.common.reflect.Types$WildcardTypeImpl cannot be cast to java.lang.reflect.TypeVariable
at org.apache.beam.sdk.coders.CoderRegistry.getCoderFromTypeDescriptor(CoderRegistry.java:623)
at org.apache.beam.sdk.coders.CoderRegistry.getCoderFromParameterizedType(CoderRegistry.java:656)
at org.apache.beam.sdk.coders.CoderRegistry.getCoderFromTypeDescriptor(CoderRegistry.java:618)
at org.apache.beam.sdk.coders.CoderRegistry.getCoder(CoderRegistry.java:252)
at org.apache.beam.sdk.values.PCollection.inferCoderOrFail(PCollection.java:149)
at org.apache.beam.sdk.values.PCollection.finishSpecifyingOutput(PCollection.java:89)
Это можно проследить в коде луча до следующей строки в org.apache.beam.sdk.coders.CoderRegistry#getCoderFromTypeDescriptor
, где тип в конечном итоге присваивается ? extends Geometry
:
else if (type instanceof WildcardType) {
// No coder for an unknown generic type.
throw new CannotProvideCoderException(
String.format("Cannot provide a coder for type variable %s"
+ " (declared by %s) because the actual type is unknown due to erasure.",
type,
((TypeVariable<?>) type).getGenericDeclaration()),
ReasonCode.TYPE_ERASURE);
}
Пример, приведенный ниже, является упрощением реальной проблемы. На самом деле я не читаю из списка строк, а из HBase, поэтому я не могу просто указать свой кодер в Create.of(data).withCoder(...)
. Тем не менее, поведение такое же.
Это ожидаемое поведение, и мне следует избегать использования групповых символов? Или я должен подойти к этому по-другому? Почему указанный кодер не используется для этого?