apache/flink · error · InvalidTypesException

Given class: {}is not a FunctionalInterface.

Error message

Given class: {}is not a FunctionalInterface.

What it means

Thrown by TypeExtractionUtils.getSingleAbstractMethod when the baseClass is not an interface (baseClass.isInterface() returns false). The method expects a functional interface (which by definition is an interface with a single abstract method). Passing a concrete class or an abstract class triggers this error. Note: the message has a missing space between the class name and 'is'.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractionUtils.java:238

            }
        } else {
            throw new InvalidTypesException(
                    "The given type " + t + " is not a parameterized type.");
        }
    }

    /**
     * Extracts a Single Abstract Method (SAM) as defined in Java Specification (4.3.2. The Class
     * Object, 9.8 Functional Interfaces, 9.4.3 Interface Method Body) from given class.
     *
     * @param baseClass a class that is a FunctionalInterface to retrieve a SAM from
     * @throws InvalidTypesException if the given class does not implement FunctionalInterface
     * @return single abstract method of the given class
     */
    public static Method getSingleAbstractMethod(Class<?> baseClass) {

        if (!baseClass.isInterface()) {
            throw new InvalidTypesException(
                    "Given class: " + baseClass + "is not a FunctionalInterface.");
        }

        Method sam = null;
        for (Method method : baseClass.getMethods()) {
            if (Modifier.isAbstract(method.getModifiers())) {
                if (sam == null) {
                    sam = method;
                } else {
                    throw new InvalidTypesException(
                            "Given class: "
                                    + baseClass
                                    + " is not a FunctionalInterface. It has more than one abstract method.");
                }
            }
        }

        if (sam == null) {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Ensure your function implements the appropriate Flink interface (e.g. MapFunction, FlatMapFunction).
  2. If you need class-based inheritance, implement ResultTypeQueryable to provide type information directly.
  3. Specify the type explicitly using .returns(TypeInformation.of(...)).

Example fix

// before
public abstract class MyMapper extends RichMapFunction { ... }
ds.map(new MyMapper() { ... })
// after
public class MyMapper implements MapFunction<String, Integer> {
    public Integer map(String s) { return s.length(); }
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!baseClass.isInterface()) {
    throw new IllegalArgumentException(
        baseClass + " must be an interface for SAM extraction");
}

Type guard

static boolean isFunctionalInterfaceCandidate(Class<?> clazz) {
    return clazz.isInterface() && clazz.getAnnotation(FunctionalInterface.class) != null;
}

Prevention

When it happens

Trigger: Calling getSingleAbstractMethod with a concrete class instead of an interface. Passing an abstract class that is not annotated @FunctionalInterface. The type extraction logic encounters a function that is not based on an interface (e.g. extending an abstract class instead of implementing an interface).

Common situations: Developer creates a custom function by extending an abstract class rather than implementing Flink's function interfaces. Using a class-based (non-interface) function implementation that bypasses the standard SAM extraction path.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/564057919b6434a4. Report an issue: GitHub.