{"record":{"id":"4851ac962f633c88","repo":"apache/hadoop","slug":"does-not-have-valid-constructor","errorCode":null,"errorMessage":"{} does not have valid constructor","messagePattern":"(.+?) does not have valid constructor","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/lib/CombineFileRecordReader.java","lineNumber":114,"sourceCode":"   * A generic RecordReader that can hand out different recordReaders\n   * for each chunk in the CombineFileSplit.\n   */\n  public CombineFileRecordReader(JobConf job, CombineFileSplit split, \n                                 Reporter reporter,\n                                 Class<RecordReader<K, V>> rrClass)\n    throws IOException {\n    this.split = split;\n    this.jc = job;\n    this.reporter = reporter;\n    this.idx = 0;\n    this.curReader = null;\n    this.progress = 0;\n\n    try {\n      rrConstructor = rrClass.getDeclaredConstructor(constructorSignature);\n      rrConstructor.setAccessible(true);\n    } catch (Exception e) {\n      throw new RuntimeException(rrClass.getName() + \n                                 \" does not have valid constructor\", e);\n    }\n    initNextRecordReader();\n  }\n  \n  /**\n   * Get the record reader for the next chunk in this CombineFileSplit.\n   */\n  protected boolean initNextRecordReader() throws IOException {\n\n    if (curReader != null) {\n      curReader.close();\n      curReader = null;\n      if (idx > 0) {\n        progress += split.getLength(idx-1);    // done processing so far\n      }\n    }\n","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/lib/CombineFileRecordReader.java#L96-L132","documentation":"CombineFileRecordReader is a generic RecordReader that processes each chunk of a CombineFileSplit by instantiating a per-chunk delegate RecordReader via reflection. It requires the delegate class to declare a constructor with the exact signature (CombineFileSplit, Configuration, Reporter, Integer) — see constructorSignature in CombineFileRecordReader.java:41. If getDeclaredConstructor() cannot find that exact constructor, the NoSuchMethodException is wrapped in this RuntimeException when the reader is created, before any record is read.","triggerScenarios":"An InputFormat extends CombineFileInputFormat and returns new CombineFileRecordReader<>(split, conf, reporter, MyRecordReader.class) where MyRecordReader lacks a public constructor (CombineFileSplit, Configuration, Reporter, Integer). Typical mismatches: taking FileSplit instead of CombineFileSplit, JobConf instead of Configuration, org.apache.hadoop.mapreduce.TaskAttemptContext instead of Reporter, int instead of Integer, or the constructor being private/absent.","commonSituations":"Porting a new-API (org.apache.hadoop.mapreduce) RecordReader into the old mapred CombineFileInputFormat flow, or copying a RecordReader written for FileSplit-based formats. Reflection requires an exact type match, so even a constructor taking JobConf (a subclass of Configuration) fails because getDeclaredConstructor is called with Configuration.class in the signature array.","solutions":["Add a constructor with the exact signature: public MyRecordReader(CombineFileSplit split, Configuration conf, Reporter reporter, Integer idx) { ... }","Make the constructor public; non-public constructors may be found by getDeclaredConstructor but setAccessible(true) can fail under a security manager","Inspect the wrapped cause (e.getCause()) — NoSuchMethodException tells you which parameter types are wrong","If you are on the new mapreduce API, use org.apache.hadoop.mapreduce.lib.input.CombineFileRecordReader with its (CombineFileSplit, TaskAttemptContext, Integer) signature instead"],"exampleFix":"// before: wrong signature -> RuntimeException \"does not have valid constructor\"\npublic MyRecordReader(FileSplit split, JobConf conf, Reporter reporter, Integer idx) { ... }\n\n// after: exact signature required by CombineFileRecordReader (line 41-45)\npublic MyRecordReader(CombineFileSplit split, Configuration conf, Reporter reporter, Integer idx) {\n  this.split = split;\n  this.idx = idx;\n}","handlingStrategy":"validation","validationCode":"// before job submission, verify the exact constructor CombineFileRecordReader needs\nstatic boolean hasRequiredCtor(Class<? extends RecordReader> rrClass) {\n  try {\n    rrClass.getDeclaredConstructor(\n        org.apache.hadoop.mapred.lib.CombineFileSplit.class,\n        org.apache.hadoop.conf.Configuration.class,\n        org.apache.hadoop.mapred.Reporter.class,\n        Integer.class);\n    return true;\n  } catch (NoSuchMethodException e) {\n    return false;\n  }\n}\nif (!hasRequiredCtor(MyRecordReader.class)) throw new RuntimeException(\"missing delegate ctor\");","typeGuard":null,"tryCatchPattern":"try {\n  return new CombineFileRecordReader<K,V>(split, conf, reporter, MyRecordReader.class);\n} catch (RuntimeException e) {\n  if (e.getCause() instanceof NoSuchMethodException) {\n    throw new IllegalStateException(\"MyRecordReader must declare ctor (CombineFileSplit, Configuration, Reporter, Integer)\", e);\n  }\n  throw e;\n}","preventionTips":["Keep one canonical delegate RecordReader per CombineFileInputFormat subclass and unit-test that its (CombineFileSplit, Configuration, Reporter, Integer) constructor exists","Treat the wrapped NoSuchMethodException as the source of truth — it names which reflective lookup failed","Add a unit test that calls getDeclaredConstructor with the signature array before shipping the job"],"tags":["hadoop","mapreduce","combinefilesplit","reflection","record-reader"],"backgroundTag":"reflection-missing-constructor","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}