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
- Verify the method exists on the class and matches the expected name/visibility: check with clazz.getMethods() before registering
- Correct the method name string in the registerUdf call
- 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
- Cross-check UDF method names in registration against the class's public static methods
- Add a startup smoke test that resolves every registered UDF name
- Avoid renaming public UDF methods without grepping registration strings
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
- No method annotated with @%s found in class %s.
- Method %s is not public.
- Unable to find factory method %s#%s(%s)
- Unable to find constructor for + factoryClass.getName()
- No UdfProvider implementation found in ${jarPath}. Create a
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/81603d96908531c6.
Report an issue: GitHub.