{"record":{"id":"61e59aa1edcfe711","repo":"apache/iceberg","slug":"class-s-does-not-implement-dynamicrecordgenerator-61e59a","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.3/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.3/flink/src/main/java/org/apache/iceberg/flink/IcebergTableSink.java#L275-L307","documentation":"Thrown when a configured DynamicRecordGeneratorSQL implementation class was loaded but its instances cannot be cast to the expected DynamicRecordGeneratorSQL interface, so Flink aborts sink construction. The buildChecked lookup matched a constructor shape, but the type does not implement the required interface.","triggerScenarios":"Setting 'write-dynamic-record-generator' (or equivalent write property) to a class name that compiles a matching constructor but does not implement org.apache.iceberg.flink.DynamicRecordGeneratorSQL; classpath conflict where two versions of the interface exist and the impl implements the wrong one.","commonSituations":"Typo'd or hand-rolled generator class; stale jar on the classpath after upgrading Iceberg so the interface was repackaged/renamed; fat-jar shading putting DynamicRecordGeneratorSQL in two different classloaders.","solutions":["Make the configured class implement DynamicRecordGeneratorSQL (and its factory/ctor contract for RowType, Map, Configuration).","Check for duplicate Iceberg jars in the Flink /lib and job jar; remove conflicting versions and rebuild shaded jar.","Verify the fully-qualified class name in the property points to the intended implementation."],"exampleFix":"// before\nproperties.setProperty(\"write.dynamic-record-generator\", \"com.example.MyGen\"); // MyGen does not implement the interface\n// after\npublic class MyGen implements DynamicRecordGeneratorSQL { ... }","handlingStrategy":"validation","validationCode":"Class<?> clz = Class.forName(generatorImpl, true, IcebergTableSink.class.getClassLoader());\nif (!DynamicRecordGeneratorSQL.class.isAssignableFrom(clz)) {\n  throw new IllegalStateException(generatorImpl + \" must implement DynamicRecordGeneratorSQL\");\n}","typeGuard":"if (obj instanceof DynamicRecordGeneratorSQL) { DynamicRecordGeneratorSQL gen = (DynamicRecordGeneratorSQL) obj; }","tryCatchPattern":null,"preventionTips":["Implement the DynamicRecordGeneratorSQL interface on every custom generator.","Keep one Iceberg version on the Flink classpath; avoid duplicate shaded jars.","Unit-test instantiation of the configured generator class before submitting jobs."],"tags":["flink","classpath","invalid-argument-value"],"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"}