{"record":{"id":"469ef47314f9eb93","repo":"apache/hadoop","slug":"failed-to-instantiate-comparator-comparator-e","errorCode":null,"errorMessage":"Failed to instantiate comparator: {comparator}({e})","messagePattern":"Failed to instantiate comparator: (.+?)\\((.+?)\\)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/file/tfile/TFile.java","lineNumber":2117,"sourceCode":"            TFILE_COMPARATOR_JCLASS_ENABLED_DEFAULT)) {\n          throw new IllegalArgumentException(\n              \"Class-name comparators are not enabled (set \"\n                  + TFILE_COMPARATOR_JCLASS_ENABLED + \"=true to allow): \"\n                  + comparator);\n        }\n        String compClassName =\n            comparator.substring(COMPARATOR_JCLASS.length()).trim();\n        try {\n          // Resolve without running the class initializer, confirm it really\n          // is a RawComparator, and only then load and construct it.\n          Class<?> compClass =\n              Class.forName(compClassName, false, conf.getClassLoader());\n          RawComparator<Object> rawComparator =\n              (RawComparator<Object>) compClass.asSubclass(RawComparator.class)\n                  .getDeclaredConstructor().newInstance();\n          return new BytesComparator(rawComparator);\n        } catch (Exception e) {\n          throw new IllegalArgumentException(\n              \"Failed to instantiate comparator: \" + comparator + \"(\"\n                  + e.toString() + \")\");\n        }\n      } else {\n        throw new IllegalArgumentException(\"Unsupported comparator: \"\n            + comparator);\n      }\n    }\n\n    public void write(DataOutput out) throws IOException {\n      TFile.API_VERSION.write(out);\n      Utils.writeVLong(out, recordCount);\n      Utils.writeString(out, strComparator);\n    }\n\n    public long getRecordCount() {\n      return recordCount;\n    }","sourceCodeStart":2099,"sourceCodeEnd":2135,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/file/tfile/TFile.java#L2099-L2135","documentation":"IllegalArgumentException from makeComparator wrapping any failure while resolving the jclass comparator: Class.forName, the RawComparator cast (asSubclass), getDeclaredConstructor(), or newInstance(). The original exception's toString() is embedded in the message, so the cause is directly readable. Preconditions to meet: class on the classpath, public no-arg constructor, implements RawComparator.","triggerScenarios":"Comparator class missing from the reader's classpath (client job jar doesn't ship it), the class lacks a public no-arg constructor, it does not implement RawComparator, or its constructor throws. Note forName is called with initialize=false, so static-initializer side effects are avoided but instance construction errors still land here.","commonSituations":"Job jars that ship the writer's comparator but not the reader's, refactoring that renamed or moved the comparator class without regenerating TFiles, comparators with only constructor-arg constructors, or comparators whose ctor throws in restricted environments.","solutions":["Read the parenthesized cause in the message: ClassNotFoundException -> ship the class; NoSuchMethodException -> add public no-arg ctor; ClassCastException -> implement RawComparator.","Ship the exact comparator class in the job jar and keep the class name stable across versions of your code.","If the ctor fails for environment reasons, fix that environment issue; the guard rethrows whatever the ctor threw."],"exampleFix":"// before\npublic class MyKeyComparator implements RawComparator<MyKey> {\n  public MyKeyComparator(MyKey proto) {} // no no-arg ctor -> always fails\n}\n// after\npublic class MyKeyComparator implements RawComparator<MyKey> {\n  public MyKeyComparator() {} // required: public, zero-arg\n  // ... compare(...) methods\n}","handlingStrategy":"validation","validationCode":"String cmpName = readerOrWriterComparatorName;\nif (cmpName != null && cmpName.startsWith(\"jclass:\")) {\n  Class<?> c = Class.forName(cmpName.substring(\"jclass:\".length()).trim(), false, conf.getClassLoader());\n  c.asSubclass(org.apache.hadoop.io.RawComparator.class).getDeclaredConstructor(); // throws early with a clear cause\n}","typeGuard":null,"tryCatchPattern":"try {\n  ...open writer/reader...\n} catch (IllegalArgumentException e) {\n  // e.getMessage() embeds the root cause; fix classpath/ctor, then retry with a NEW reader\n}","preventionTips":["Ship the comparator class in every job jar that reads or writes the files.","Require a public no-arg constructor and RawComparator implementation, enforced by a compile-time test.","Keep comparator class names stable; regeneration is the only fix after a rename."],"tags":["tfile","hadoop-common","comparator","reflection","classpath","instantiation"],"backgroundTag":"reflection-instantiation-failed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}