apache/beam · error · RuntimeException

Unable to instantiate ExternalTransformBuilder from construc

Error message

Unable to instantiate ExternalTransformBuilder from constructor.

What it means

Beam's expansion service discovers ExternalTransformBuilder implementations via ServiceLoader and instantiates each with a no-arg constructor. If instantiation fails for any reason other than a RuntimeException (e.g. IllegalAccessException, InvocationTargetException from a throwing constructor, missing class), it is wrapped in this RuntimeException.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/expansion/ExternalTransformRegistrar.java:68

    ImmutableMap.Builder builder = ImmutableMap.<String, ExternalTransformBuilder>builder();
    Map<String, Class<? extends ExternalTransformBuilder<?, ?, ?>>> knownBuilders = knownBuilders();
    for (Entry<String, Class<? extends ExternalTransformBuilder<?, ?, ?>>> knownBuilder :
        knownBuilders.entrySet()) {
      Preconditions.checkState(
          ExternalTransformBuilder.class.isAssignableFrom(knownBuilder.getValue()),
          "Provided identifier %s is not an ExternalTransformBuilder.",
          knownBuilder.getValue().getName());
      try {
        Constructor<? extends ExternalTransformBuilder> constructor =
            knownBuilder.getValue().getDeclaredConstructor();

        constructor.setAccessible(true);
        builder.put(knownBuilder.getKey(), constructor.newInstance());

      } catch (RuntimeException e) {
        throw e;
      } catch (Exception e) {
        throw new RuntimeException(
            "Unable to instantiate ExternalTransformBuilder from constructor.", e);
      }
    }
    return builder.build();
  }
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure the builder class has a public no-arg constructor and keep it side-effect free.
  2. Check the expansion service classpath includes the builder class and all its dependencies.
  3. Inspect the cause (e.getCause()) for the constructor's underlying failure and fix that initialization error.

Example fix

// before
class MyBuilder implements ExternalTransformBuilder<...> {
  MyBuilder(Config c) { ... } // no no-arg constructor
}
// after
class MyBuilder implements ExternalTransformBuilder<...> {
  public MyBuilder() {} // required by ExternalTransformRegistrar
}
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = Class.forName(builderName);
if (!java.lang.reflect.Modifier.isPublic(c.getModifiers()) || c.getConstructors().length == 0)
  throw new IllegalStateException("needs public no-arg constructor: " + builderName);

Try / catch

try { registrar.knownBuilderInstances(); } catch (RuntimeException e) { log.error("builder init failed", e.getCause()); throw e; }

Prevention

When it happens

Trigger: Registering an ExternalTransformBuilder whose class has no accessible no-arg constructor, whose constructor throws during initialization, or which depends on classes not present in the expansion service classpath.

Common situations: Cross-language transform expansion: a Java transform JAR not fully shipped to the expansion service, a builder requiring injected state via constructor, constructor performing eager validation that fails (missing config/env).

Related errors


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