apache/beam · error · RuntimeException

No matching constructor found for class

Error message

No matching constructor found for class ${clazz}

What it means

AvroByteBuddyUtils generates fast object constructors for Avro SpecificRecords via ByteBuddy. It expects the record class to have a constructor whose parameter count equals the schema's field count; if none is found it throws RuntimeException.

Solutions

  1. Use an Avro-generated SpecificRecord class matching the schema (regenerate with avro-maven-plugin)
  2. Ensure the schema passed matches the class's actual fields
  3. Fall back to reflection-based conversion instead of ByteBuddy (set the appropriate AvroUtils option)

Example fix

// before
AvroByteBuddyUtils.getTypeCreator(myPlainPojoClass, schema);
// after (regenerate class from schema first)
mvn generate-sources // avro-maven-plugin produces MyRecord with matching constructor
AvroByteBuddyUtils.getTypeCreator(MyRecord.class, schema);
Defensive patterns

Strategy: validation

Validate before calling

long ctors = Arrays.stream(clazz.getConstructors())
    .filter(c -> c.getParameterCount() == schema.getFieldCount()).count();
if (ctors == 0) throw new IllegalStateException(clazz + " has no constructor matching " + schema.getFieldCount() + " fields");

Type guard

static boolean hasMatchingConstructor(Class<?> c, Schema s) {
  return Arrays.stream(c.getConstructors())
      .anyMatch(k -> k.getParameterCount() == s.getFields().size());
}

Try / catch

try { getCreator(clazz, schema); } catch (RuntimeException e) { /* fall back to reflection-based conversion */ }

Prevention

When it happens

Trigger: Calling AvroByteBuddyUtils.getCreator (used by AvroSchemaUtil / converters) with a class whose declared constructors don't match the schema field count — e.g. non-SpecificRecord classes, manually edited records, or a schema whose fieldCount disagrees with the generated class.

Common situations: Using AvroSchemaUtil.toJavaBean-style conversion with plain POJOs instead of Avro-generated classes, stale generated classes after schema evolution, or hand-written classes implementing SpecificRecord.

Related errors


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

Appendix: source

Thrown at sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroByteBuddyUtils.java:76

      Maps.newConcurrentMap();

  static <T extends SpecificRecord> SchemaUserTypeCreator getCreator(
      Class<T> clazz, Schema schema) {
    return CACHED_CREATORS.computeIfAbsent(
        ClassWithSchema.create(clazz, schema), c -> createCreator(clazz, schema));
  }

  private static <T> SchemaUserTypeCreator createCreator(Class<T> clazz, Schema schema) {
    Constructor baseConstructor = null;
    Constructor[] constructors = clazz.getDeclaredConstructors();
    for (Constructor constructor : constructors) {
      // TODO: This assumes that Avro only generates one constructor with this many fields.
      if (constructor.getParameterCount() == schema.getFieldCount()) {
        baseConstructor = constructor;
      }
    }
    if (baseConstructor == null) {
      throw new RuntimeException("No matching constructor found for class " + clazz);
    }

    // Generate a method call to create and invoke the SpecificRecord's constructor. .
    MethodCall construct = MethodCall.construct(baseConstructor);
    for (int i = 0; i < baseConstructor.getParameterTypes().length; ++i) {
      Class<?> baseType = baseConstructor.getParameterTypes()[i];
      construct = construct.with(readAndConvertParameter(baseType, i), baseType);
    }

    try {
      DynamicType.Builder<SchemaUserTypeCreator> builder =
          BYTE_BUDDY
              .with(new InjectPackageStrategy(clazz))
              .subclass(SchemaUserTypeCreator.class)
              .method(ElementMatchers.named("create"))
              .intercept(construct);

      return builder

View on GitHub (pinned to 12126d8942)