apache/beam · error · java.lang.IllegalArgumentException

Could not instantiate class

Error message

Could not instantiate class 

What it means

The expansion service tried to load and instantiate the user-supplied transform class via reflection but failed. It wraps ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, or IllegalArgumentException thrown during Class.forName(...) and newInstance() in getTransform. This means the class could not be found on the expansion service classpath or could not be constructed with a no-arg constructor.

Solutions

  1. Add the JAR containing the transform class to the expansion service classpath (build a custom expansion service that includes your transform dependency).
  2. Verify the fully-qualified class name in the expansion request is correct and matches the deployed artifact version.
  3. Ensure the class is public, concrete (not abstract/interface), and has an accessible no-arg constructor.
  4. Check the wrapped cause ('Caused by') in the exception to distinguish ClassNotFoundException vs constructor failure and fix accordingly.

Example fix

// before: running stock expansion service
java -jar beam-expansion-service.jar
// after: shadow JAR that bundles your transform
./gradlew shadowJar && java -jar my-expansion-service.jar  # includes mytransforms dependency
Defensive patterns

Strategy: try-catch

Validate before calling

Class<?> c;
try { c = Class.forName(fqcn); } catch (ClassNotFoundException e) { throw new IllegalStateException("Transform not on expansion service classpath: " + fqcn); }
if (c.isInterface() || java.lang.reflect.Modifier.isAbstract(c.getModifiers())) throw new IllegalStateException("Transform must be concrete");
try { c.getDeclaredConstructor().setAccessible(true); } catch (NoSuchMethodException e) { throw new IllegalStateException("Transform lacks a no-arg constructor"); }

Type guard

function canInstantiate(fqcn) {
  try { const c = java.lang.Class.forName(fqcn);
    return !c.isInterface() && !java.lang.reflect.Modifier.isAbstract(c.getModifiers()) && c.getConstructor();
  } catch (e) { return false; }
}

Try / catch

try {
  PTransform<PInput, POutput> t = provider.getTransform(payload);
} catch (IllegalArgumentException e) {
  log.error("Transform instantiation failed: {}", e.getMessage(), e.getCause()); // inspect 'Caused by' for ClassNotFoundException vs ctor failure
  throw new ExpansionSetupException(fqcn + " missing or not instantiable on service classpath", e);
}

Prevention

When it happens

Trigger: Calling ExpansionService / expand with a transform identifier whose class is absent from the service's classpath; the class is abstract, an interface, or lacks an accessible no-arg constructor; the class's constructor throws an exception; or a security/visibility issue blocks reflective access.

Common situations: Deploying a pipeline against a stock Beam expansion service JAR without bundling the custom transform's JAR; typos or wrong fully-qualified class names in pipeline payloads; fat-jar shading excluding the transform; class constructor performing DI or throwing at init time.

Related errors


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

Appendix: source

Thrown at sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java:137

                constructorRow,
                constructor.getGenericParameterTypes());
        transform = (PTransform<PInput, POutput>) constructor.newInstance(parameterValues);
      } else {
        Method[] methods = transformClass.getMethods();
        Method method = findMappingConstructorMethod(methods, payload, allowlistClass);
        Object[] parameterValues =
            getParameterValues(
                method.getParameters(), constructorRow, method.getGenericParameterTypes());
        transform = (PTransform<PInput, POutput>) method.invoke(null /* static */, parameterValues);
      }
      return applyBuilderMethods(transform, payload, allowlistClass);
    } catch (ClassNotFoundException e) {
      throw new IllegalArgumentException("Could not find class " + className, e);
    } catch (InstantiationException
        | IllegalArgumentException
        | IllegalAccessException
        | InvocationTargetException e) {
      throw new IllegalArgumentException("Could not instantiate class " + className, e);
    }
  }

  @SuppressWarnings("assignment")
  private PTransform<PInput, POutput> applyBuilderMethods(
      PTransform<PInput, POutput> transform,
      JavaClassLookupPayload payload,
      AllowedClass allowListClass) {
    for (BuilderMethod builderMethod : payload.getBuilderMethodsList()) {
      Method method = getMethod(transform, builderMethod, allowListClass);
      try {
        Row builderMethodRow = decodeRow(builderMethod.getSchema(), builderMethod.getPayload());
        transform =
            (PTransform<PInput, POutput>)
                method.invoke(
                    transform,
                    getParameterValues(
                        method.getParameters(),

View on GitHub (pinned to 12126d8942)