--- model: sonnet --- # AP06 – Bootstrap und CLI-Adapter > **Meilenstein:** M1 > **Vorgänger:** AP05 ✅ erforderlich > **Nachfolger:** AP07, AP09 > **Grundlage:** `docs/specs/technik-und-architektur.md` v5, §§ „CLI-Zuschnitt", „Laufzeit- und Betriebsmodell", „Gültigkeitsentscheidung und Exit-Codes", „Zeichensätze" > **Entscheidungsprotokoll:** `docs/arbeitspakete/m1/E00-entscheidungsprotokoll.md` (E-05 fat JAR) ## Ziel Die bestehende `AsvValidatorApplication` wird in zwei klar getrennte Verantwortlichkeiten zerlegt: 1. **Bootstrap** (`de.gecheckt.asv.bootstrap.Main`) — verdrahtet alle Komponenten manuell per Constructor Injection, ist der einzige `public static void main` 2. **CLI-Adapter** (`de.gecheckt.asv.adapter.in.cli.CliRunner`) — nimmt CLI-Argumente entgegen, ruft Application-Schicht auf, übersetzt Ergebnis in Exit-Code Zusätzlich werden Exit-Codes spec-konform auf `0/1/2` umgestellt, ISO-8859-15 als Eingabe-Encoding eingeführt, und das Uber-JAR via `maven-shade-plugin` gebaut. ## Voraussetzungen - AP03, AP04, AP05 ## Scope IN ### Bootstrap (`de.gecheckt.asv.bootstrap.Main`) - `public static void main(String[] args)` - Verdrahtet manuell per Constructor Injection: - `LoggingConfigurator` - `CliRunner` - Application-Service (in M1 noch Dummy-Pfad — Datei lesen, leeren `ValidationReport` zurückgeben) - Ruft `CliRunner.run(args)` auf und gibt den Exit-Code an `System.exit` weiter - Log4j2-Typen dürfen **nur** hier und in `adapter.out.logging` sichtbar sein ### CLI-Adapter (`de.gecheckt.asv.adapter.in.cli.CliRunner`) - Methode `int run(String[] args)` - Akzeptiert **genau ein Positionsargument**: Pfad zur Eingabedatei - Bei 0 oder ≥ 2 Argumenten → Exit-Code `2`, kurze deutsche Fehlermeldung auf STDERR (vollständiger Minimalbericht kommt in AP08) - Bei nicht existierender, nicht lesbarer oder nicht regulärer Eingabedatei → Exit-Code `2` - Bei erfolgreichem Lauf ohne Spec-Fehler → Exit-Code `0` - Bei erfolgreichem Lauf mit Spec-Fehlern → Exit-Code `1` ### Exit-Code-Konstanten Konstanten **nur noch in einer Klasse** (z.B. `ExitCode` im Paket `adapter.in.cli`): ```java public final class ExitCode { public static final int VALID = 0; public static final int INVALID = 1; public static final int OPERATIONAL_ERROR = 2; private ExitCode() {} } ``` Die alten Konstanten (`EXIT_CODE_INVALID_ARGUMENTS=1`, `EXIT_CODE_FILE_ERROR=2`, `EXIT_CODE_VALIDATION_ERRORS=3`) werden **gelöscht**. ### Verdrahtung mit Befundmodell (AP05) - `CliRunner` nutzt `ValidationReport.computeVerdict()` zur Exit-Code-Ableitung - Im Bedienfehlerfall: `ValidationReport.operationalError(...)` → Exit-Code `2` - Der eigentliche M1-Dummy-Pfad: Datei wird gelesen (ISO-8859-15), Bytes gezählt, leerer `ValidationReport` mit `fileName` und `timestamp` zurückgegeben. **Keine echte Validierung in M1.** ### Zeichensatz-Korrektur Beim Einlesen der Eingabedatei wird **ISO-8859-15** verwendet: ```java // Korrekt: Charset iso = Charset.forName("ISO-8859-15"); // NICHT: StandardCharsets.UTF_8 // NICHT: Charset.defaultCharset() ``` JDK-21-Verfügbarkeit per Test belegen: Eine Datei mit Byte `0xA4` ergibt beim Einlesen das Euro-Zeichen `€`, weil `0xA4` in ISO-8859-15 auf Euro-Zeichen liegt. ### Uber-JAR via `maven-shade-plugin` `maven-jar-plugin`-Platzhalter aus AP02 ersetzen durch `maven-shade-plugin`: ```xml org.apache.maven.plugins maven-shade-plugin package shade de.gecheckt.asv.bootstrap.Main *:* META-INF/*.SF META-INF/*.DSA META-INF/*.RSA ``` `java -jar target/asv-format-validator-*.jar ` muss ohne `-cp` funktionieren. ### `.gitignore` — `logs/` ergänzen `logs/` zum `.gitignore` hinzufügen (gemäß E-04 aus Entscheidungsprotokoll). Der statische Dateipfad aus AP04 wird nach AP07 durch dynamische Logdatei ersetzt. ## Scope OUT - Berichtdatei und Log-Datei im Eingabeverzeichnis (AP07) - Vollständiger Minimalbericht bei Exit-Code `2` (AP08) - Entkopplung der Altlogik (AP09) - Architekturtest (AP10) ## Schritte 1. `de.gecheckt.asv.bootstrap.Main` anlegen 2. `CliRunner` in `adapter.in.cli` anlegen 3. `ExitCode`-Konstantenklasse anlegen 4. `AsvValidatorApplication` schrittweise entkernen: Code wandert nach `CliRunner` und `Main` 5. Einlese-Encoding auf `Charset.forName("ISO-8859-15")` umstellen 6. `maven-shade-plugin` in `pom.xml` einbinden, `maven-jar-plugin`-Platzhalter entfernen 7. `logs/` in `.gitignore` ergänzen 8. Alle Tests die auf `AsvValidatorApplication` direkt zeigen auf `CliRunner` umziehen 9. `mvn clean package` — erzeugtes JAR mit `java -jar target/asv-format-validator-*.jar ` manuell prüfen 10. `mvn clean verify` grün bekommen 11. Abschlussbericht schreiben ## Abnahmekriterien - [ ] `de.gecheckt.asv.bootstrap.Main` existiert und ist `Main-Class` des Uber-JAR - [ ] `CliRunner` ist der einzige Ort mit CLI-Argument-Parsing - [ ] Exit-Codes `0`, `1`, `2` sind definiert und spec-konform eingesetzt, kein Exit-Code `3` mehr erreichbar - [ ] Test: Aufruf ohne Argument → Exit-Code `2` - [ ] Test: Aufruf mit nicht existierender Datei → Exit-Code `2` - [ ] Test: Aufruf mit leerer, lesbarer Datei → Exit-Code `0` - [ ] Einlese-Encoding ist ISO-8859-15 (per Test belegt: Byte `0xA4` → `€`) - [ ] `java -jar target/asv-format-validator-*.jar ` startet ohne `-cp` - [ ] `logs/` in `.gitignore` - [ ] Keine Log4j2-Typen außerhalb von `bootstrap` und `adapter.out.logging` - [ ] `mvn clean verify` grün - [ ] Abschlussbericht unter `docs/arbeitspakete/m1/berichte/AP06-bericht.md` ## Rest-Risiken und offene Punkte - Der Dummy-Pfad (Datei lesen, leerer Report) ist bewusst dünn. Echte Parser-/Validator-Einbindung kommt in M3+. - Nicht versuchen, in AP06 schon die alte Parser-/Validator-Kette mit dem neuen Modell zu verknüpfen — das ist AP09-Scope. - `maven-shade-plugin` mit Log4j2 benötigt den `Log4j2PluginsCacheFileTransformer`, sonst werden Log4j2-Plugins nicht korrekt geladen. ## Bericht `docs/arbeitspakete/m1/berichte/AP06-bericht.md` nach `docs/arbeitspakete/m1/templates/ap-bericht.md`.