Использование кодера с универсальными шаблонами - PullRequest
0 голосов
/ 14 мая 2018

У меня есть преобразование, которое выводит тип с подстановочным знаком: 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(...). Тем не менее, поведение такое же.

Это ожидаемое поведение, и мне следует избегать использования групповых символов? Или я должен подойти к этому по-другому? Почему указанный кодер не используется для этого?

...