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

  1. Mark the @ApplyMethod method public.
  2. Also ensure the ScalarFn class itself is public so reflection can access the method.
  3. 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

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


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