{"record":{"id":"dde0675149015136","repo":"apache/hadoop","slug":"unable-to-construct-journal","errorCode":null,"errorMessage":"Unable to construct journal, {}","messagePattern":"Unable to construct journal, (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLog.java","lineNumber":1896,"sourceCode":"  JournalManager createJournal(URI uri) {\n    Class<? extends JournalManager> clazz\n      = getJournalClass(conf, uri.getScheme());\n\n    try {\n      Constructor<? extends JournalManager> cons\n        = clazz.getConstructor(Configuration.class, URI.class,\n            NamespaceInfo.class, String.class);\n      String nameServiceId = conf.get(DFSConfigKeys.DFS_NAMESERVICE_ID);\n      return cons.newInstance(conf, uri, storage.getNamespaceInfo(),\n          nameServiceId);\n    } catch (NoSuchMethodException ne) {\n      try {\n        Constructor<? extends JournalManager> cons\n            = clazz.getConstructor(Configuration.class, URI.class,\n            NamespaceInfo.class);\n        return cons.newInstance(conf, uri, storage.getNamespaceInfo());\n      } catch (Exception e) {\n        throw new IllegalArgumentException(\"Unable to construct journal, \"\n            + uri, e);\n      }\n    } catch (Exception e) {\n      throw new IllegalArgumentException(\"Unable to construct journal, \"\n                                         + uri, e);\n    }\n  }\n\n  @VisibleForTesting\n  // needed by async impl to restart thread when edit log is replaced by a\n  // spy because a spy is a shallow copy\n  public void restart() {\n  }\n\n  /**\n   * Return total number of syncs happened on this edit log.\n   * @return long - count\n   */","sourceCodeStart":1878,"sourceCodeEnd":1914,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLog.java#L1878-L1914","documentation":"FSEditLog.createJournal first looks for the 4-argument constructor (Configuration, URI, NamespaceInfo, String nameServiceId); on NoSuchMethodException it falls back to the legacy 3-argument constructor (Configuration, URI, NamespaceInfo). This catch fires when the fallback also fails: the class implements neither constructor signature, or its 3-arg constructor threw during newInstance. Everything is wrapped in IllegalArgumentException('Unable to construct journal, <uri>') with the real cause chained.","triggerScenarios":"Deploying a custom JournalManager whose constructors match neither (Configuration, URI, NamespaceInfo, String) nor (Configuration, URI, NamespaceInfo): for example a class built for a Hadoop version with a different factory or constructor contract, or one exposing constructors with extra parameters.","commonSituations":"Plugin recompiled against Hadoop trunk and deployed on branch-2 (or the reverse); plugin upgraded without changing its constructor; binary copied between clusters running different Hadoop lines.","solutions":["Give the JournalManager class a public constructor (Configuration, URI, NamespaceInfo, String nameServiceId), the preferred signature, or the legacy (Configuration, URI, NamespaceInfo)","Recompile the plugin against the exact Hadoop version running the NameNode","Read the chained cause in the NameNode log: NoSuchMethodException at the root means signature mismatch; InvocationTargetException means the constructor itself threw"],"exampleFix":"// before: only a Configuration-only constructor exists\npublic MyJournalManager(Configuration conf) { ... }\n\n// after: supported signature resolved by FSEditLog.createJournal\npublic MyJournalManager(Configuration conf, URI uri,\n    NamespaceInfo nsInfo, String nameServiceId) { ... }","handlingStrategy":"validation","validationCode":"// deploy-time check: the plugin must expose a supported constructor\nClass<?> c = Class.forName(className);\nboolean ok = false;\ntry { c.getConstructor(Configuration.class, URI.class,\n    NamespaceInfo.class, String.class); ok = true; } catch (NoSuchMethodException ignore) { }\ntry { c.getConstructor(Configuration.class, URI.class,\n    NamespaceInfo.class); ok = true; } catch (NoSuchMethodException ignore) { }\nif (!ok) throw new IllegalStateException(\n    className + \" has no supported JournalManager constructor\");","typeGuard":null,"tryCatchPattern":"try {\n  // FSEditLog construction with custom journal URIs\n} catch (IllegalArgumentException e) {\n  Throwable root = e;\n  while (root.getCause() != null) root = root.getCause();\n  if (root instanceof NoSuchMethodException) {\n    // signature mismatch: recompile plugin with a (Configuration, URI,\n    // NamespaceInfo[, String]) constructor\n  }\n  throw e;\n}","preventionTips":["Build the plugin against the exact Hadoop version in production","Add an integration test that constructs the journal with a dummy URI and NamespaceInfo before shipping","Pin the constructor signature in the plugin's build checks"],"tags":["hdfs","namenode","edit-log","journal-manager","reflection","constructor","api-mismatch"],"backgroundTag":"constructor-signature-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}