{"record":{"id":"edcf418eacfdc14e","repo":"apache/druid","slug":"this-jobby-does-not-implement-getjobstats-jobby","errorCode":null,"errorMessage":"This Jobby does not implement getJobStats(), Jobby class: [%s]","messagePattern":"This Jobby does not implement getJobStats\\(\\), Jobby class: \\[(.+?)\\]","errorType":"exception","errorClass":"UOE","httpStatus":null,"severity":"warning","filePath":"processing/src/main/java/org/apache/druid/indexer/Jobby.java","lineNumber":39,"sourceCode":"\nimport org.apache.druid.java.util.common.UOE;\n\nimport javax.annotation.Nullable;\nimport java.util.Map;\n\n/**\n */\npublic interface Jobby\n{\n  boolean run();\n\n  /**\n   * @return A map containing statistics for a Jobby, optionally null if the Jobby is unable to provide stats.\n   */\n  @Nullable\n  default Map<String, Object> getStats()\n  {\n    throw new UOE(\"This Jobby does not implement getJobStats(), Jobby class: [%s]\", getClass());\n  }\n\n  /**\n   * @return A string representing the error that caused a Jobby to fail. Can be null if the Jobby did not fail,\n   * or is unable to provide an error message.\n   */\n  @Nullable\n  default String getErrorMessage()\n  {\n    throw new UOE(\"This Jobby does not implement getErrorMessage(), Jobby class: [%s]\", getClass());\n  }\n}\n","sourceCodeStart":21,"sourceCodeEnd":52,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/indexer/Jobby.java#L21-L52","documentation":"Jobby's default getStats() implementation is a stub that throws UOE. A Jobby implementation that does not override getJobStats()-equivalent stats access causes this error when someone asks for job statistics.","triggerScenarios":"Calling getStats() on a Jobby implementation (e.g. a custom job or one of Druid's simple Jobby implementations) that has not overridden getStats().","commonSituations":"Custom HadoopDruidIndexer job extensions; monitoring/reporting code that uniformly calls getStats() on all jobs in a JobbyContainer.","solutions":["Override getStats() in the Jobby implementation to return the job's stats map.","Avoid calling getStats() on implementations known not to support stats (or check instanceof a stats-capable type).","Wrap the call in try-catch for UOE and treat stats as unavailable."],"exampleFix":"// before\nclass MyJob implements Jobby { /* no getStats */ }\n// after\n@Override\n@Nullable\npublic Map<String, Object> getStats() { return myStatsMap; }","handlingStrategy":"try-catch","validationCode":"if (!(job instanceof StatsCapableJobby)) { return null; }","typeGuard":"boolean supportsStats(Object job) { try { job.getClass().getMethod(\"getStats\"); return true; } catch (NoSuchMethodException e) { return false; } }","tryCatchPattern":"try { stats = job.getStats(); } catch (UOE e) { log.warn(\"Stats unsupported for {}: {}\", job.getClass(), e.getMessage()); stats = null; }","preventionTips":["Override getStats() in every custom Jobby implementation","Do not assume all Jobby implementations expose stats","Default stats to null/absent in monitoring code"],"tags":["unsupported-operation","hadoop-indexer","interface-default"],"backgroundTag":"method-not-implemented","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}