apache/pulsar · error · IllegalArgumentException

Window function does not implement the correct interface

Error message

Window function does not implement the correct interface

What it means

initializeUserFunction validates that the user-supplied function object implements one of the supported interfaces: java.util.function.Function (with Collection input) or the Pulsar WindowFunction interface. If the provided object implements neither, this IllegalArgumentException is thrown at instance initialization. It signals user code is incompatible with the windowing executor.

Source

Thrown at pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java:86

    @SuppressWarnings("unchecked")
    private void initializeUserFunction(WindowConfig windowConfig) {
        String actualWindowFunctionClassName = windowConfig.getActualWindowFunctionClassName();
        ClassLoader clsLoader = Thread.currentThread().getContextClassLoader();
        Object userClassObject = Reflections.createInstance(
                actualWindowFunctionClassName,
                clsLoader);
        if (userClassObject instanceof java.util.function.Function) {
            Class<?>[] typeArgs = TypeResolver.resolveRawArguments(
                    java.util.function.Function.class, userClassObject.getClass());
            if (typeArgs[0].equals(Collection.class)) {
                bareWindowFunction = (java.util.function.Function<Collection<T>, X>) userClassObject;
            } else {
                throw new IllegalArgumentException("Window function must take a collection as input");
            }
        } else if (userClassObject instanceof WindowFunction) {
            windowFunction = (WindowFunction<T, X>) userClassObject;
        } else {
            throw new IllegalArgumentException("Window function does not implement the correct interface");
        }
    }

    private WindowConfig getWindowConfigs(Context context) {

        if (!context.getUserConfigValue(WindowConfig.WINDOW_CONFIG_KEY).isPresent()) {
            throw new IllegalArgumentException("Window Configs cannot be found");
        }
        WindowConfig windowConfig = new Gson().fromJson(
                (new Gson().toJson(context.getUserConfigValue(WindowConfig.WINDOW_CONFIG_KEY).get())),
                WindowConfig.class);

        return windowConfig;
    }

    private WindowManager<Record<T>> getWindowManager(WindowConfig windowConfig, Context context) {

        WindowLifecycleListener<Event<Record<T>>> lifecycleListener = newWindowLifecycleListener(context);

View on GitHub (pinned to 820761864e)

Solutions

  1. Implement org.apache.pulsar.functions.api.windowing.WindowFunction<T,X> in the user class
  2. Or implement java.util.function.Function<Collection<T>, X> with Collection as the input type
  3. Verify the jar deployed to the function actually contains the updated class (rebuild and redeploy)
  4. Check imports: use the windowing WindowFunction, not a same-named class from another library

Example fix

// before
class MyFunc implements java.util.function.Consumer<String> { ... }
// after
class MyFunc implements WindowFunction<String, Void> {
    public Void process(Collection<String> input, Window window) { ...; return null; }
}
Defensive patterns

Strategy: type-guard

Validate before calling

boolean ok = WindowFunction.class.isAssignableFrom(fnClass)
    || java.util.function.Function.class.isAssignableFrom(fnClass);
if (!ok) throw new IllegalArgumentException("class must implement WindowFunction or Function<Collection<T>,X>");

Type guard

static boolean isWindowFunctionClass(Class<?> c) {
    return WindowFunction.class.isAssignableFrom(c)
        || java.util.function.Function.class.isAssignableFrom(c);
}

Try / catch

try {
    executor.initialize();
} catch (IllegalArgumentException e) {
    throw new IllegalStateException("function class incompatible with windowing executor: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: The class configured as the function implements some other functional interface (e.g. custom interface, Consumer, BiFunction) or a raw Object; instanceof checks against both supported interfaces fail during initialize.

Common situations: Passing a transformer/processor class from a non-windowing pipeline into a windowed function config; refactoring renamed the base interface; loading a stale jar compiled against a different WindowFunction package.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/2c0c4507655e4a15. Report an issue: GitHub.