apache/beam · error · RuntimeException

Unable to generate a creator for class {} with schema {}

Error message

Unable to generate a creator for class {} with schema {}

What it means

createStaticCreator builds a creator around a class's declared zero-argument constructor and throws this RuntimeException when instantiation fails, for the same reflective reasons as error 384. It is invoked from getStaticCreator for types that were determined to use a static/zero-arg creation path.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/POJOUtils.java:279

              .with(new InjectPackageStrategy(clazz))
              .subclass(SchemaUserTypeCreator.class)
              .method(ElementMatchers.named("create"))
              .intercept(
                  new StaticFactoryMethodInstruction(
                      types, clazz, creator, typeConversionsFactory));

      return builder
          .visit(new AsmVisitorWrapper.ForDeclaredMethods().writerFlags(ClassWriter.COMPUTE_FRAMES))
          .make()
          .load(ReflectHelpers.findClassLoader(), getClassLoadingStrategy(clazz))
          .getLoaded()
          .getDeclaredConstructor()
          .newInstance();
    } catch (InstantiationException
        | IllegalAccessException
        | NoSuchMethodException
        | InvocationTargetException e) {
      throw new RuntimeException(
          "Unable to generate a creator for class " + clazz + " with schema " + schema);
    }
  }

  /**
   * Generate the following {@link FieldValueSetter} class for the {@link Field}.
   *
   * <pre><code>
   *   class Getter implements {@literal FieldValueGetter<POJO, FieldType>} {
   *     {@literal @}Override public String name() { return field.getName(); }
   *     {@literal @}Override public Class type() { return field.getType(); }
   *     {@literal @}Override public FieldType get(POJO pojo) {
   *        return convert(pojo.field);
   *      }
   *   }
   * </code></pre>
   */
  static <ObjectT, ValueT> FieldValueGetter<@NonNull ObjectT, ValueT> createGetter(

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure the class has a public zero-argument constructor.
  2. Annotate a factory method with @SchemaCreate if zero-arg construction isn't valid for the type.
  3. Verify the class name/type registered in the pipeline matches a concrete instantiable class.
  4. Reproduce the reflective call manually to surface the real cause (InstantiationException vs NoSuchMethodException).

Example fix

// before
public abstract class BaseRecord { } // abstract, cannot instantiate
// after
public class ConcreteRecord extends BaseRecord {
  public ConcreteRecord() { }
}
Defensive patterns

Strategy: validation

Validate before calling

if (Modifier.isAbstract(clazz.getModifiers()) || clazz.isInterface()
    || java.util.Arrays.stream(clazz.getDeclaredConstructors()).noneMatch(c -> c.getParameterCount() == 0)) {
  throw new IllegalStateException(clazz + " cannot be used with createStaticCreator");
}

Try / catch

try {
  SchemaUserTypeCreator creator = POJOUtils.getStaticCreator(typeDescriptor, schema);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Unable to generate a creator for class")) {
    // register a concrete, instantiable class instead
  } else throw e;
}

Prevention

When it happens

Trigger: getStaticCreator -> createStaticCreator on a class whose getDeclaredConstructor() finds no zero-arg constructor, or whose constructor is inaccessible, or the class is abstract/interface, or the constructor throws.

Common situations: Registry/configured class names that don't match the expected POJO shape, refactored classes losing their no-arg constructor, or classes instantiated reflectively at runtime on a different classloader.

Related errors


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