apache/hadoop · error · RuntimeException

{} does not have valid constructor

Error message

{} does not have valid constructor

What it means

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.

Source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/lib/CombineFileRecordReader.java:114

   * A generic RecordReader that can hand out different recordReaders
   * for each chunk in the CombineFileSplit.
   */
  public CombineFileRecordReader(JobConf job, CombineFileSplit split, 
                                 Reporter reporter,
                                 Class<RecordReader<K, V>> rrClass)
    throws IOException {
    this.split = split;
    this.jc = job;
    this.reporter = reporter;
    this.idx = 0;
    this.curReader = null;
    this.progress = 0;

    try {
      rrConstructor = rrClass.getDeclaredConstructor(constructorSignature);
      rrConstructor.setAccessible(true);
    } catch (Exception e) {
      throw new RuntimeException(rrClass.getName() + 
                                 " does not have valid constructor", e);
    }
    initNextRecordReader();
  }
  
  /**
   * Get the record reader for the next chunk in this CombineFileSplit.
   */
  protected boolean initNextRecordReader() throws IOException {

    if (curReader != null) {
      curReader.close();
      curReader = null;
      if (idx > 0) {
        progress += split.getLength(idx-1);    // done processing so far
      }
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Add a constructor with the exact signature: public MyRecordReader(CombineFileSplit split, Configuration conf, Reporter reporter, Integer idx) { ... }
  2. Make the constructor public; non-public constructors may be found by getDeclaredConstructor but setAccessible(true) can fail under a security manager
  3. Inspect the wrapped cause (e.getCause()) — NoSuchMethodException tells you which parameter types are wrong
  4. If you are on the new mapreduce API, use org.apache.hadoop.mapreduce.lib.input.CombineFileRecordReader with its (CombineFileSplit, TaskAttemptContext, Integer) signature instead

Example fix

// before: wrong signature -> RuntimeException "does not have valid constructor"
public MyRecordReader(FileSplit split, JobConf conf, Reporter reporter, Integer idx) { ... }

// after: exact signature required by CombineFileRecordReader (line 41-45)
public MyRecordReader(CombineFileSplit split, Configuration conf, Reporter reporter, Integer idx) {
  this.split = split;
  this.idx = idx;
}
Defensive patterns

Strategy: validation

Validate before calling

// before job submission, verify the exact constructor CombineFileRecordReader needs
static boolean hasRequiredCtor(Class<? extends RecordReader> rrClass) {
  try {
    rrClass.getDeclaredConstructor(
        org.apache.hadoop.mapred.lib.CombineFileSplit.class,
        org.apache.hadoop.conf.Configuration.class,
        org.apache.hadoop.mapred.Reporter.class,
        Integer.class);
    return true;
  } catch (NoSuchMethodException e) {
    return false;
  }
}
if (!hasRequiredCtor(MyRecordReader.class)) throw new RuntimeException("missing delegate ctor");

Try / catch

try {
  return new CombineFileRecordReader<K,V>(split, conf, reporter, MyRecordReader.class);
} catch (RuntimeException e) {
  if (e.getCause() instanceof NoSuchMethodException) {
    throw new IllegalStateException("MyRecordReader must declare ctor (CombineFileSplit, Configuration, Reporter, Integer)", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/4851ac962f633c88. Report an issue: GitHub.