Search in sources :

Example 1 with CannotProvideCoderException

use of org.apache.beam.sdk.coders.CannotProvideCoderException in project beam by apache.

the class Create method getDefaultCreateCoder.

private static <T> Coder<T> getDefaultCreateCoder(CoderRegistry registry, Iterable<T> elems) throws CannotProvideCoderException {
    checkArgument(!Iterables.isEmpty(elems), "Can not determine a default Coder for a 'Create' PTransform that " + "has no elements.  Either add elements, call Create.empty(Coder)," + " Create.empty(TypeDescriptor), or call 'withCoder(Coder)' or " + "'withType(TypeDescriptor)' on the PTransform.");
    // First try to deduce a coder using the types of the elements.
    Class<?> elementClazz = Void.class;
    for (T elem : elems) {
        if (elem == null) {
            continue;
        }
        Class<?> clazz = elem.getClass();
        if (elementClazz.equals(Void.class)) {
            elementClazz = clazz;
        } else if (!elementClazz.equals(clazz)) {
            // Elements are not the same type, require a user-specified coder.
            throw new CannotProvideCoderException(String.format("Cannot provide coder for %s: The elements are not all of the same class.", Create.class.getSimpleName()));
        }
    }
    if (elementClazz.getTypeParameters().length == 0) {
        try {
            // elementClazz is a wildcard type
            @SuppressWarnings("unchecked") Coder<T> coder = (Coder<T>) registry.getCoder(TypeDescriptor.of(elementClazz));
            return coder;
        } catch (CannotProvideCoderException exc) {
        // Can't get a coder from the class of the elements, try with the elements next
        }
    }
    // If that fails, try to deduce a coder using the elements themselves
    return (Coder<T>) inferCoderFromObjects(registry, elems);
}
Also used : TimestampedValueCoder(org.apache.beam.sdk.values.TimestampedValue.TimestampedValueCoder) Coder(org.apache.beam.sdk.coders.Coder) ListCoder(org.apache.beam.sdk.coders.ListCoder) SetCoder(org.apache.beam.sdk.coders.SetCoder) MapCoder(org.apache.beam.sdk.coders.MapCoder) KvCoder(org.apache.beam.sdk.coders.KvCoder) IterableCoder(org.apache.beam.sdk.coders.IterableCoder) CollectionCoder(org.apache.beam.sdk.coders.CollectionCoder) VoidCoder(org.apache.beam.sdk.coders.VoidCoder) CannotProvideCoderException(org.apache.beam.sdk.coders.CannotProvideCoderException)

Example 2 with CannotProvideCoderException

use of org.apache.beam.sdk.coders.CannotProvideCoderException in project beam by apache.

the class PCollection method inferCoderOrFail.

/**
   * If the coder is not explicitly set, this sets the coder for this {@link PCollection} to the
   * best coder that can be inferred based upon the known {@link TypeDescriptor}. By default, this
   * is null, but can and should be improved by subclasses.
   */
@SuppressWarnings({ "unchecked", "rawtypes" })
private CoderOrFailure<T> inferCoderOrFail(PInput input, PTransform<?, ?> transform, CoderRegistry registry) {
    // First option for a coder: use the Coder set on this PValue.
    if (coderOrFailure.coder != null) {
        return coderOrFailure;
    }
    // Second option for a coder: use the default Coder from the producing PTransform.
    CannotProvideCoderException inputCoderException;
    try {
        return new CoderOrFailure<>(((PTransform) transform).getDefaultOutputCoder(input, this), null);
    } catch (CannotProvideCoderException exc) {
        inputCoderException = exc;
    }
    // Third option for a coder: Look in the coder registry.
    TypeDescriptor<T> token = getTypeDescriptor();
    CannotProvideCoderException inferFromTokenException = null;
    if (token != null) {
        try {
            return new CoderOrFailure<>(registry.getCoder(token), null);
        } catch (CannotProvideCoderException exc) {
            inferFromTokenException = exc;
            // and the error message itself.
            if (transform instanceof ParDo.MultiOutput && exc.getReason() == ReasonCode.TYPE_ERASURE) {
                inferFromTokenException = new CannotProvideCoderException(exc.getMessage() + " If this error occurs for an output of the producing ParDo, verify that the " + "TupleTag for this output is constructed with proper type information (see " + "TupleTag Javadoc) or explicitly set the Coder to use if this is not possible.");
            }
        }
    }
    // Build up the error message and list of causes.
    StringBuilder messageBuilder = new StringBuilder().append("Unable to return a default Coder for ").append(this).append(". Correct one of the following root causes:");
    // No exception, but give the user a message about .setCoder() has not been called.
    messageBuilder.append("\n  No Coder has been manually specified; ").append(" you may do so using .setCoder().");
    if (inferFromTokenException != null) {
        messageBuilder.append("\n  Inferring a Coder from the CoderRegistry failed: ").append(inferFromTokenException.getMessage());
    }
    if (inputCoderException != null) {
        messageBuilder.append("\n  Using the default output Coder from the producing PTransform failed: ").append(inputCoderException.getMessage());
    }
    // Build and throw the exception.
    return new CoderOrFailure<>(null, messageBuilder.toString());
}
Also used : CannotProvideCoderException(org.apache.beam.sdk.coders.CannotProvideCoderException)

Example 3 with CannotProvideCoderException

use of org.apache.beam.sdk.coders.CannotProvideCoderException in project beam by apache.

the class WithKeys method expand.

@Override
public PCollection<KV<K, V>> expand(PCollection<V> in) {
    PCollection<KV<K, V>> result = in.apply("AddKeys", MapElements.via(new SimpleFunction<V, KV<K, V>>() {

        @Override
        public KV<K, V> apply(V element) {
            return KV.of(fn.apply(element), element);
        }
    }));
    try {
        Coder<K> keyCoder;
        CoderRegistry coderRegistry = in.getPipeline().getCoderRegistry();
        if (keyClass == null) {
            keyCoder = coderRegistry.getOutputCoder(fn, in.getCoder());
        } else {
            keyCoder = coderRegistry.getCoder(TypeDescriptor.of(keyClass));
        }
        // TODO: Remove when we can set the coder inference context.
        result.setCoder(KvCoder.of(keyCoder, in.getCoder()));
    } catch (CannotProvideCoderException exc) {
    // let lazy coder inference have a try
    }
    return result;
}
Also used : CoderRegistry(org.apache.beam.sdk.coders.CoderRegistry) CannotProvideCoderException(org.apache.beam.sdk.coders.CannotProvideCoderException) KV(org.apache.beam.sdk.values.KV) KV(org.apache.beam.sdk.values.KV)

Example 4 with CannotProvideCoderException

use of org.apache.beam.sdk.coders.CannotProvideCoderException in project beam by apache.

the class ParDo method codersForStateSpecTypes.

/**
   * Try to provide coders for as many of the type arguments of given
   * {@link DoFnSignature.StateDeclaration} as possible.
   */
private static <InputT> Coder[] codersForStateSpecTypes(DoFnSignature.StateDeclaration stateDeclaration, CoderRegistry coderRegistry, Coder<InputT> inputCoder) {
    Type stateType = stateDeclaration.stateType().getType();
    if (!(stateType instanceof ParameterizedType)) {
        // No type arguments means no coders to infer.
        return new Coder[0];
    }
    Type[] typeArguments = ((ParameterizedType) stateType).getActualTypeArguments();
    Coder[] coders = new Coder[typeArguments.length];
    for (int i = 0; i < typeArguments.length; i++) {
        Type typeArgument = typeArguments[i];
        TypeDescriptor<?> typeDescriptor = TypeDescriptor.of(typeArgument);
        try {
            coders[i] = coderRegistry.getCoder(typeDescriptor);
        } catch (CannotProvideCoderException e) {
            try {
                coders[i] = coderRegistry.getCoder(typeDescriptor, inputCoder.getEncodedTypeDescriptor(), inputCoder);
            } catch (CannotProvideCoderException ignored) {
            // Since not all type arguments will have a registered coder we ignore this exception.
            }
        }
    }
    return coders;
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) Coder(org.apache.beam.sdk.coders.Coder) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) CannotProvideCoderException(org.apache.beam.sdk.coders.CannotProvideCoderException)

Example 5 with CannotProvideCoderException

use of org.apache.beam.sdk.coders.CannotProvideCoderException in project beam by apache.

the class KafkaIO method inferCoder.

/**
   * Attempt to infer a {@link Coder} by extracting the type of the deserialized-class from the
   * deserializer argument using the {@link Coder} registry.
   */
@VisibleForTesting
static <T> NullableCoder<T> inferCoder(CoderRegistry coderRegistry, Class<? extends Deserializer<T>> deserializer) {
    checkNotNull(deserializer);
    for (Type type : deserializer.getGenericInterfaces()) {
        if (!(type instanceof ParameterizedType)) {
            continue;
        }
        // This does not recurse: we will not infer from a class that extends
        // a class that extends Deserializer<T>.
        ParameterizedType parameterizedType = (ParameterizedType) type;
        if (parameterizedType.getRawType() == Deserializer.class) {
            Type parameter = parameterizedType.getActualTypeArguments()[0];
            @SuppressWarnings("unchecked") Class<T> clazz = (Class<T>) parameter;
            try {
                return NullableCoder.of(coderRegistry.getCoder(clazz));
            } catch (CannotProvideCoderException e) {
                throw new RuntimeException(String.format("Unable to automatically infer a Coder for " + "the Kafka Deserializer %s: no coder registered for type %s", deserializer, clazz));
            }
        }
    }
    throw new RuntimeException(String.format("Could not extract the Kafka Deserializer type from %s", deserializer));
}
Also used : ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) ParameterizedType(java.lang.reflect.ParameterizedType) CannotProvideCoderException(org.apache.beam.sdk.coders.CannotProvideCoderException) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Aggregations

CannotProvideCoderException (org.apache.beam.sdk.coders.CannotProvideCoderException)6 ParameterizedType (java.lang.reflect.ParameterizedType)2 Type (java.lang.reflect.Type)2 Coder (org.apache.beam.sdk.coders.Coder)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 FluentIterable (com.google.common.collect.FluentIterable)1 CoderRegistry (org.apache.beam.sdk.coders.CoderRegistry)1 CollectionCoder (org.apache.beam.sdk.coders.CollectionCoder)1 IterableCoder (org.apache.beam.sdk.coders.IterableCoder)1 KvCoder (org.apache.beam.sdk.coders.KvCoder)1 ListCoder (org.apache.beam.sdk.coders.ListCoder)1 MapCoder (org.apache.beam.sdk.coders.MapCoder)1 SetCoder (org.apache.beam.sdk.coders.SetCoder)1 VoidCoder (org.apache.beam.sdk.coders.VoidCoder)1 Combine (org.apache.beam.sdk.transforms.Combine)1 CombineWithContext (org.apache.beam.sdk.transforms.CombineWithContext)1 WindowedValue (org.apache.beam.sdk.util.WindowedValue)1 KV (org.apache.beam.sdk.values.KV)1 TimestampedValueCoder (org.apache.beam.sdk.values.TimestampedValue.TimestampedValueCoder)1 JavaSparkContext (org.apache.spark.api.java.JavaSparkContext)1