{"record":{"id":"4aaf2833c85b507f","repo":"apache/hadoop","slug":"stopwatch-is-already-running","errorCode":null,"errorMessage":"StopWatch is already running","messagePattern":"StopWatch is already running","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/StopWatch.java","lineNumber":60,"sourceCode":"  public StopWatch(Timer timer) {\n    this.timer = timer;\n  }\n\n  /**\n   * The method is used to find out if the StopWatch is started.\n   * @return boolean If the StopWatch is started.\n   */\n  public boolean isRunning() {\n    return isStarted;\n  }\n\n  /**\n   * Start to measure times and make the state of stopwatch running.\n   * @return this instance of StopWatch.\n   */\n  public StopWatch start() {\n    if (isStarted) {\n      throw new IllegalStateException(\"StopWatch is already running\");\n    }\n    isStarted = true;\n    startNanos = timer.monotonicNowNanos();\n    return this;\n  }\n\n  /**\n   * Stop elapsed time and make the state of stopwatch stop.\n   * @return this instance of StopWatch.\n   */\n  public StopWatch stop() {\n    if (!isStarted) {\n      throw new IllegalStateException(\"StopWatch is already stopped\");\n    }\n    long now = timer.monotonicNowNanos();\n    isStarted = false;\n    currentElapsedNanos += now - startNanos;\n    return this;","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/StopWatch.java#L42-L78","documentation":"org.apache.hadoop.util.StopWatch accumulates elapsed time across start()/stop() pairs. start() throws IllegalStateException when the watch is already running — a second start without an intervening stop (or reset) is a state-machine violation, not a time measurement.","triggerScenarios":"Calling watch.start() twice: instrumentation added at two layers wrapping the same watch; restart in a loop iteration that forgot stop(); timing code copy-pasted around a method that already started it.","commonSituations":"Refactoring moves a start() into a helper that callers also start; benchmark loops that start at the top of each iteration but only stop conditionally; watches shared across try blocks with early continues.","solutions":["Check state first: if (watch.isRunning()) watch.stop(); before start()","Use reset() when you want a fresh measurement: watch.reset().start() (reset clears elapsed and stops the watch)","Pair start/stop in try/finally so every start has exactly one stop","Since StopWatch implements Closeable, prefer try (StopWatch sw = new StopWatch().start()) { ... } which stops on close"],"exampleFix":"// before\nwatch.start();\ndoWork();\nwatch.start();   // IllegalStateException\n\n// after\nwatch.start();\ndoWork();\nwatch.stop();\nwatch.reset();   // elapsed cleared, watch stopped\nwatch.start();   // fresh interval is now legal","handlingStrategy":"validation","validationCode":"if (watch.isRunning()) {\n  watch.stop(); // close the previous interval first\n}\nwatch.start();","typeGuard":null,"tryCatchPattern":"try { watch.start(); } catch (IllegalStateException e) { /* watch already running: stop() or reset() before restarting */ }","preventionTips":["Always pair start() with stop() in try/finally so the watch never stays running","Use reset() to return to a known stopped-and-zero state before a new measurement","Exploit StopWatch implementing Closeable: try (StopWatch sw = new StopWatch().start()) { ... }","Keep one owner per watch — never share a running watch across layers"],"tags":["hadoop","stopwatch","timing","illegalstate","api-misuse"],"backgroundTag":"invalid-object-state","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}