From 719cc50d1670455a3ecfc35b960864798336efbe Mon Sep 17 00:00:00 2001 From: Marcus van Elst Date: Thu, 7 May 2026 12:14:43 +0200 Subject: [PATCH] Bugfix V3.2: RunLockPort-JavaDoc korrigiert und Backup-Fehler bei aktivem Scheduler behoben BUG 1: RunLockPort-JavaDoc dokumentierte den Scheduler-Tick faelschlicherweise als nicht-blockierenden Pfad mit tryAcquire(). Da execute() intern acquire() aufruft, wuerde tryAcquire() vor execute() einen Double-Lock erzeugen. JavaDoc korrigiert: Scheduler-Tick nutzt denselben blockierenden acquire()-Pfad wie der manuelle Lauf. BUG 2: GuiConfigurationPropertiesWriter.copyFile() faengt jetzt AccessDeniedException separat ab und liefert den klaren Hinweis "Konfiguration kann nicht gespeichert werden - Scheduler laeuft." statt einer generischen Fehlermeldung. Co-Authored-By: Claude Sonnet 4.6 --- .../application/port/out/RunLockPort.java | 14 +++++++------- .../adapter/GuiConfigurationPropertiesWriter.java | 4 ++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/out/RunLockPort.java b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/out/RunLockPort.java index d5088ab..70ad1c7 100644 --- a/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/out/RunLockPort.java +++ b/pdf-umbenenner-application/src/main/java/de/gecheckt/pdf/umbenenner/application/port/out/RunLockPort.java @@ -16,18 +16,18 @@ import java.util.Optional; *
  • Kontrollierten Startabbruch ermöglichen, wenn bereits eine Instanz läuft
  • * *

    - * Lock-Lifecycle (blockierender Pfad – headless und manueller GUI-Lauf): + * Lock-Lifecycle (blockierender Pfad – headless, manueller GUI-Lauf und Scheduler-Tick): *

      *
    1. Lock beim Laufstart erwerben ({@link #acquire()})
    2. *
    3. Lock für die gesamte Dauer des Laufs halten
    4. *
    5. Lock am Laufende freigeben ({@link #release()}), auch bei Fehler
    6. *
    - * Lock-Lifecycle (nicht-blockierender Pfad – Scheduler-Tick): - *
      - *
    1. Lock nicht-blockierend versuchen ({@link #tryAcquire()})
    2. - *
    3. Bei leerem Optional sofort mit {@code SkippedBusy} abbrechen
    4. - *
    5. Bei vorhandenem Handle in try-with-resources verwenden
    6. - *
    + * Der Scheduler-Tick verwendet dieselbe blockierende Methode {@link #acquire()} wie + * der manuelle Laufpfad. {@link BatchRunProcessingUseCase#execute execute()} ruft + * {@link #acquire()} intern auf; das Ergebnis {@code LOCK_UNAVAILABLE} signalisiert + * dem Aufrufer, dass ein paralleler Lauf aktiv ist. + * {@link #tryAcquire()} ist für Aufrufer vorgesehen, die außerhalb des Use-Case + * einen schnellen, nicht-blockierenden Lock-Versuch benötigen. */ public interface RunLockPort { diff --git a/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/adapter/GuiConfigurationPropertiesWriter.java b/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/adapter/GuiConfigurationPropertiesWriter.java index bd1df95..984b4cd 100644 --- a/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/adapter/GuiConfigurationPropertiesWriter.java +++ b/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/adapter/GuiConfigurationPropertiesWriter.java @@ -2,6 +2,7 @@ package de.gecheckt.pdf.umbenenner.bootstrap.adapter; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.nio.file.AccessDeniedException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; @@ -156,6 +157,9 @@ public final class GuiConfigurationPropertiesWriter implements GuiConfigurationF private void copyFile(Path source, Path destination) { try { Files.copy(source, destination); + } catch (AccessDeniedException e) { + throw new GuiConfigurationWriteException( + "Konfiguration kann nicht gespeichert werden – Scheduler läuft.", e); } catch (IOException e) { throw new GuiConfigurationWriteException( "Sicherungskopie konnte nicht erstellt werden: " + destination, e);