apache/beam · error · IllegalArgumentException
Method %s is not public.
Error message
Method %s is not public.
What it means
The selected @ApplyMethod must be public so Beam can invoke it reflectively across package boundaries. getApplyMethod checks the resolved method's modifiers and throws IllegalArgumentException if it is package-private, protected, or private.
Source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/ScalarFnReflector.java:67
// 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
- Mark the @ApplyMethod method public.
- Also ensure the ScalarFn class itself is public so reflection can access the method.
- If Java module access is a concern, keep the class public and avoid JPMS strong encapsulation of the package.
Example fix
// before
@ApplyMethod String apply(String s) { ... }
// after
@ApplyMethod public String apply(String s) { ... } Defensive patterns
Strategy: validation
Validate before calling
static void checkApplyMethodPublic(ScalarFn fn) throws Exception {
java.lang.reflect.Method m = ScalarFnReflector.getApplyMethod(fn);
if (!java.lang.reflect.Modifier.isPublic(m.getModifiers()))
throw new IllegalStateException("@ApplyMethod must be public: " + m);
} Try / catch
try {
ScalarFnReflector.getApplyMethod(scalarFn);
} catch (IllegalArgumentException e) {
if (e.getMessage().endsWith("is not public.")) {
throw new IllegalStateException("Make the @ApplyMethod method public in " + scalarFn.getClass(), e);
}
throw e;
} Prevention
- Make both the ScalarFn class and its @ApplyMethod method public.
- Review IDE-generated method stubs for default (package-private) visibility.
- Add a reflection-based startup check in tests for all registered UDFs.
When it happens
Trigger: Declaring the @ApplyMethod-annotated method with non-public visibility in a ScalarFn subclass, then registering it as a Beam SQL scalar function.
Common situations: IDE-generated apply stubs defaulting to package-private; making the method protected to 'restrict' it; moving the method into an interface-less package-private class during refactoring.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- No method annotated with @%s found in class %s.
- Cannot create UDF from method: method %s.%s not found
- No UdfProvider implementation found in ${jarPath}. Create a
- Cannot get type arguments for %s: must implement parameteriz
- Found multiple methods annotated with @%s. [%s] and [%s]
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/826c5124bb0b447e.
Report an issue: GitHub.