apache/beam · error · RuntimeException

Cannot create UDF from method: method %s.%s not found

Error message

Cannot create UDF from method: method %s.%s not found

What it means

UdfImpl.create(Class, String) resolves a UDF by reflective method lookup (findMethod) in the given class; when no method with that name exists it throws a RuntimeException wrapping the class canonical name and method name. The library cannot build a Calcite Function without an actual Method handle.

Source

Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/UdfImpl.java:47

class UdfImpl {

  private UdfImpl() {}

  /**
   * Creates {@link org.apache.beam.vendor.calcite.v1_40_0.org.apache.calcite.schema.Function} from
   * given class.
   *
   * <p>If a method of the given name is not found or it does not suit, returns {@code null}.
   *
   * @param clazz class that is used to implement the function
   * @param methodName Method name (typically "eval")
   * @return created {@link Function}
   */
  public static Function create(Class<?> clazz, String methodName) {
    final @Nullable Method method = findMethod(clazz, methodName);

    if (method == null) {
      throw new RuntimeException(
          String.format(
              "Cannot create UDF from method: method %s.%s not found",
              clazz.getCanonicalName(), methodName));
    }

    return create(method);
  }

  /**
   * Creates {@link org.apache.beam.vendor.calcite.v1_40_0.org.apache.calcite.schema.Function} from
   * given method.
   *
   * @param method method that is used to implement the function
   * @return created {@link Function} or null
   */
  public static Function create(Method method) {
    if (TranslatableTable.class.isAssignableFrom(method.getReturnType())) {
      return checkArgumentNotNull(

View on GitHub (pinned to 12126d8942)

Solutions

  1. Verify the method exists on the class and matches the expected name/visibility: check with clazz.getMethods() before registering
  2. Correct the method name string in the registerUdf call
  3. Confirm you are loading the intended class/jar version (print clazz.getCanonicalName() and list its methods)

Example fix

// before
sqlEnv.registerUdf("MY_FN", MyUdfs.class, "my_fnn"); // typo
// after
sqlEnv.registerUdf("MY_FN", MyUdfs.class, "myFn");
Defensive patterns

Strategy: try-catch

Validate before calling

boolean ok = Arrays.stream(MyUdfs.class.getMethods())
    .anyMatch(m -> m.getName().equals("myFn"));
if (!ok) throw new IllegalArgumentException("myFn not found on MyUdfs");

Try / catch

try {
  Function f = UdfImpl.create(MyUdfs.class, methodName);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Cannot create UDF from method")) {
    throw new IllegalStateException("Check UDF method name: " + e.getMessage(), e);
  } else throw e;
}

Prevention

When it happens

Trigger: registerUdf(...) called with a method name that does not exist on the supplied class, is misspelled, is not public/static in the way findMethod expects, or the wrong Class object was passed.

Common situations: Typos in the UDF method name in configuration or registration code; renaming/refactoring the Java method without updating UDF registration; loading the class via a different classloader or version of the jar than expected.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/81603d96908531c6. Report an issue: GitHub.