apache/beam · error · IllegalArgumentException
Found multiple methods annotated with @%s. [%s] and [%s]
Error message
Found multiple methods annotated with @%s. [%s] and [%s]
What it means
After collecting all @ApplyMethod-annotated methods of a ScalarFn, getApplyMethod allows multiple matches only if they are overrides of each other (same name and parameter types, inherited from parent classes). If two distinct annotated methods with different names or signatures are found, the invocation target is ambiguous and an IllegalArgumentException naming both methods is thrown.
Source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/ScalarFnReflector.java:56
Collection<Method> matches =
ReflectHelpers.declaredMethodsWithAnnotation(
ScalarFn.ApplyMethod.class, clazz, ScalarFn.class);
if (matches.isEmpty()) {
throw new IllegalArgumentException(
String.format(
"No method annotated with @%s found in class %s.",
ScalarFn.ApplyMethod.class.getSimpleName(), clazz.getName()));
}
// If we have at least one match, then either it should be the only match
// or it should be an extension of the other matches (which came from parent
// classes).
Method first = matches.iterator().next();
for (Method other : matches) {
if (!first.getName().equals(other.getName())
|| !Arrays.equals(first.getParameterTypes(), other.getParameterTypes())) {
throw new IllegalArgumentException(
String.format(
"Found multiple methods annotated with @%s. [%s] and [%s]",
ScalarFn.ApplyMethod.class.getSimpleName(),
ReflectHelpers.formatMethod(first),
ReflectHelpers.formatMethod(other)));
}
}
// Method must be public.
if ((first.getModifiers() & Modifier.PUBLIC) == 0) {
throw new IllegalArgumentException(
String.format("Method %s is not public.", ReflectHelpers.formatMethod(first)));
}
return first;
}
}
View on GitHub (pinned to 12126d8942)
Solutions
- Keep exactly one logical @ApplyMethod method per ScalarFn; annotate only the one you want invoked.
- For overloads, remove @ApplyMethod from all but the target overload or split into separate ScalarFn classes.
- If a parent and child override the same signature, that is allowed — make the signatures identical (same parameter types) so it is recognized as an override.
- Search the class hierarchy (including superclasses) for stray @ApplyMethod annotations and remove them.
Example fix
// before
@ApplyMethod public String apply(String s) { ... }
@ApplyMethod public String apply(String s, Integer n) { ... } // ambiguous
// after
@ApplyMethod public String apply(String s) { ... }
public String apply(String s, Integer n) { ... } // unannotated helper Defensive patterns
Strategy: validation
Validate before calling
static void checkSingleApplyMethod(ScalarFn fn) {
java.util.Set<String> sigs = new java.util.HashSet<>();
for (java.lang.reflect.Method m : fn.getClass().getMethods()) {
if (m.isAnnotationPresent(ScalarFn.ApplyMethod.class)
&& !sigs.add(m.getName() + java.util.Arrays.toString(m.getParameterTypes())))
throw new IllegalStateException("multiple distinct @ApplyMethod methods in " + fn.getClass());
}
} Try / catch
try {
ScalarFnReflector.getApplyMethod(scalarFn);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Found multiple methods")) {
throw new IllegalStateException("Keep only one @ApplyMethod overload per ScalarFn", e);
}
throw e;
} Prevention
- Annotate only one overload of apply; leave helpers unannotated.
- Split multi-signature UDFs into separate ScalarFn classes.
- Search superclasses for stray @ApplyMethod annotations.
When it happens
Trigger: A ScalarFn class (or its superclass chain) declares two @ApplyMethod-annotated methods with different signatures or names — e.g. apply(String) and apply(String, Integer) both annotated, or two differently named methods both marked @ApplyMethod.
Common situations: Overloading the apply method and annotating every overload; adding a second apply for a new type during refactoring; a superclass and subclass each annotating genuinely different methods.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- No method annotated with @%s found in class %s.
- Failed to create SchemaProvider +providerClass.getSimpleName
- A method marked with SchemaCreate in class {} does not retur
- Expected to find a single mapping constructor but found ${ma
- Expected to find a single mapping constructor method but fou
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/e144fd0aa150faf7.
Report an issue: GitHub.