{"record":{"id":"ef81f5630d98e2b6","repo":"apache/iceberg","slug":"class-s-does-not-implement-dynamicrecordgenerator-ef81f5","errorCode":null,"errorMessage":"Class %s does not implement DynamicRecordGeneratorSQL","messagePattern":"Class (.+?) does not implement DynamicRecordGeneratorSQL","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/IcebergTableSink.java","lineNumber":293,"sourceCode":"            .withProperties(tableProperties)\n            .create();\n  }\n\n  private DynamicTableRecordGenerator createDynamicRecordGenerator(String generatorImpl) {\n    RowType rowType = (RowType) resolvedSchema.toSourceRowDataType().getLogicalType();\n\n    DynConstructors.Ctor<DynamicTableRecordGenerator> ctor;\n\n    try {\n      ctor =\n          DynConstructors.builder(DynamicTableRecordGenerator.class)\n              .loader(IcebergTableSink.class.getClassLoader())\n              .impl(generatorImpl, RowType.class)\n              .impl(generatorImpl, RowType.class, Map.class, Configuration.class)\n              .buildChecked();\n      return ctor.newInstance(rowType, writeProps, fromReadableConfig());\n    } catch (ClassCastException e) {\n      throw new IllegalArgumentException(\n          String.format(\"Class %s does not implement DynamicRecordGeneratorSQL\", generatorImpl), e);\n    } catch (Exception e) {\n      throw new RuntimeException(\n          String.format(\"Failed to instantiate DynamicRecordGeneratorSQL %s\", generatorImpl), e);\n    }\n  }\n\n  private Configuration fromReadableConfig() {\n    return readableConfig instanceof Configuration\n        ? (Configuration) readableConfig\n        : Configuration.fromMap(readableConfig.toMap());\n  }\n}\n","sourceCodeStart":275,"sourceCodeEnd":307,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/IcebergTableSink.java#L275-L307","documentation":"IcebergTableSink.createDynamicRecordGenerator loads a user-supplied DynamicRecordGeneratorSQL implementation via reflection and casts it to the expected interface; if the configured class does not implement DynamicRecordGeneratorSQL, the ClassCastException is rethrown as this IllegalArgumentException with the class name.","triggerScenarios":"Setting the dynamic record generator property (write.dynamic-record-generator or equivalent write property) to a class name that exists but implements a different interface or an older/newer interface version.","commonSituations":"Copy-pasting a generator class name from another Iceberg version; classpath pollution with duplicate/old Iceberg jars providing a different DynamicRecordGeneratorSQL; typo'd fully-qualified class name resolving to the wrong class.","solutions":["Verify the configured class implements org.apache.iceberg.flink.DynamicRecordGeneratorSQL with both (RowType) and (RowType, Map, Configuration) constructors","Check the classpath for stale/multiple Iceberg versions (mvn dependency:tree) and align versions","Correct the fully-qualified class name in the write property"],"exampleFix":"// before\nwrite.dynamic-record-generator=com.example.MyGen (implements old interface)\n// after\nwrite.dynamic-record-generator=com.example.MyGen implements DynamicRecordGeneratorSQL {\n  MyGen(RowType t); MyGen(RowType t, Map<String,String> props, Configuration c);\n}","handlingStrategy":"validation","validationCode":"Class<?> c = Class.forName(generatorImpl);\nif (!DynamicRecordGeneratorSQL.class.isAssignableFrom(c)) {\n  throw new IllegalArgumentException(generatorImpl + \" must implement DynamicRecordGeneratorSQL\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  generator = sink.createDynamicRecordGenerator(rowType);\n} catch (IllegalArgumentException e) {\n  LOG.error(\"Generator {} does not implement DynamicRecordGeneratorSQL; check classpath/versions\", generatorImpl, e);\n  throw e;\n}","preventionTips":["Keep one Iceberg version on the Flink classpath (check dependency:tree)","Verify the interface with instanceof in the generator's own tests","Use the exact fully-qualified class name from the same Iceberg build"],"tags":["flink","reflection","config"],"backgroundTag":"class-not-found","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}