{"record":{"id":"b70814e1d1191b38","repo":"GoogleContainerTools/jib","slug":"interrupted-while-trying-to-acquire-lock","errorCode":null,"errorMessage":"Interrupted while trying to acquire lock","messagePattern":"Interrupted while trying to acquire lock","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"warning","filePath":"jib-core/src/main/java/com/google/cloud/tools/jib/filesystem/LockFile.java","lineNumber":61,"sourceCode":"    this.outputStream = outputStream;\n  }\n\n  /**\n   * Creates a lock file.\n   *\n   * @param lockFile the path of the lock file\n   * @return a new {@link LockFile} that can be released later\n   * @throws IOException if creating the lock file fails\n   */\n  public static LockFile lock(Path lockFile) throws IOException {\n    try {\n      // This first lock is to prevent multiple threads from calling FileChannel.lock(), which would\n      // otherwise throw OverlappingFileLockException\n      lockMap.computeIfAbsent(lockFile, key -> new ReentrantLock()).lockInterruptibly();\n\n    } catch (InterruptedException ex) {\n      Thread.currentThread().interrupt();\n      throw new IOException(\"Interrupted while trying to acquire lock\", ex);\n    }\n\n    Files.createDirectories(lockFile.getParent());\n    FileOutputStream outputStream = new FileOutputStream(lockFile.toFile());\n    FileLock fileLock = null;\n    try {\n      fileLock = outputStream.getChannel().lock();\n      return new LockFile(lockFile, fileLock, outputStream);\n\n    } finally {\n      if (fileLock == null) {\n        outputStream.close();\n      }\n    }\n  }\n\n  /** Releases the lock file. */\n  @Override","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/GoogleContainerTools/jib/blob/fb949e2676afbbd7dd7a1ef61e20251931325654/jib-core/src/main/java/com/google/cloud/tools/jib/filesystem/LockFile.java#L43-L79","documentation":"Jib's LockFile guards cross-process cache access with a JVM-internal ReentrantLock plus a filesystem FileLock. This IOException is thrown when the thread waiting on the in-JVM ReentrantLock is interrupted before it can acquire it. The thread's interrupt flag is restored before throwing.","triggerScenarios":"Calling LockFile.lock() (via Jib cache/registry operations) from a thread that gets interrupted while another thread in the same JVM already holds the ReentrantLock for the same lock file.","commonSituations":"Task cancellation in build tools (Gradle/Maven daemon shutdown), executor shutdownNow() while Jib builds an image, timeouts implemented via thread interruption.","solutions":["Avoid interrupting threads while Jib image build steps are running; check executor shutdown logic","Catch the IOException in your build/copy task and handle cancellation gracefully","Find and eliminate sources of spurious interruption (e.g. Timer, cancel(true)) around Jib calls","Retry the Jib operation after clearing the interruption if cancellation was unintended"],"exampleFix":"// before\ntry {\n  jibContainerBuilder.containerize(containerizer);\n} catch (IOException e) {\n  throw e; // may be lock interruption\n}\n// after\ntry {\n  jibContainerBuilder.containerize(containerizer);\n} catch (IOException e) {\n  if (Thread.currentThread().isInterrupted()) {\n    Thread.interrupted(); // intentional cancellation, do not retry\n    throw e;\n  }\n  throw new BuildException(\"Transient lock failure, safe to retry\", e);\n}","handlingStrategy":"try-catch","validationCode":"if (Thread.currentThread().isInterrupted()) { throw new CancellationException(\"Already interrupted; skipping Jib operation\"); }","typeGuard":"boolean canRunJibOperation(Thread t) { return !t.isInterrupted() && !t.isAlive() == false; } // check interruption before launching","tryCatchPattern":"try { jibBuilder.containerize(containerizer); } catch (IOException e) { if (Thread.currentThread().isInterrupted()) { /* intentional cancel: rethrow */ throw new CancellationException(e.getMessage()); } throw e; }","preventionTips":["Do not call shutdownNow()/cancel(true) on threads running Jib builds unless you intend to cancel them","Scope Jib operations so interruption only happens at safe cancellation points","Check Thread.interrupted() after catching IOException to distinguish cancellation from I/O failure"],"tags":["concurrency","interrupted-thread","io-exception","locking"],"backgroundTag":"thread-interrupted","analyzedSha":"fb949e2676afbbd7dd7a1ef61e20251931325654","analyzedAt":"2026-09-06T14:04:09.491Z","contentChangedAt":"2026-09-06T14:04:09.491Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}