Modul 17 · Migration Deep Dive · Stufe 2 Java Core

Java I/O und NIO

File und manuelles Ressourcenmanagement wird nachvollziehbar in Path, Files und Try-with-resources überführt. Die Akte zeigt nicht nur das Ziel, sondern die tatsächlichen Dateien, APIs, Dependencies, Codebelege, Tests, Risiken und Cutover-Schritte.

AdapterResource Management
1 → 1Produktionsdateien
29 → 30Java-Zeilen
1 → 1Testdateien
0 / 0Dependencies entfernt / neu
NIEDRIGRisiko · Score 0

Was sich konkret ändert

DimensionLegacyModernMigrationskonsequenz
Programmiermodellimperativ / ohne Framework-Annotationenexplizite Java-AbstraktionenAnnotationen und Containerfunktionen werden nur dort eingesetzt, wo sie eine konkrete technische Verantwortung übernehmen.
Abhängigkeiten1 direkte Dependencies1 direkte Dependencies0 neu, 0 entfernt; Versionen und transitive Auswirkungen im erfolgreichen Online-Build prüfen.
Öffentliche API1 erkannte Methoden3 erkannte MethodenMethoden werden nach fachlicher Rolle gemappt; reine Bootstrap- und Framework-Methoden sind kein fachlicher Vertrag.
Datenmodellclass LegacyFileCopyclass PathFileServiceFeldnamen, IDs, Null-Semantik, Gleichheit und Serialisierungsform werden separat regressionstestet.
FehlerverhaltenLegacy-Exceptions und Rückgabewerteexplizitere Fach-/Framework-FehlerabbildungFehler dürfen nicht nur technisch übersetzt werden; Status, Ursache, Retrybarkeit und Client-Vertrag müssen erhalten oder versioniert werden.
TestsBestands- und Golden-Master-TestsUnit-, Slice-, Contract- und IntegrationstestsDer Modern-Pfad wird zuerst gegen denselben fachlichen Vektor geprüft und danach um neue technische Risiken ergänzt.
BetriebLegacy-Start/Lifecyclemodernes Packaging, Health und externe KonfigurationUmstellung über kleine Adapter und Golden-Master-Tests statt Big Bang.
RollbackLegacy-Artefakt bleibt unverändertModern-Artefakt getrennt deploybarKein Rollback über Datenverlust: Schema, Nachrichten und verschlüsselte Daten müssen rückwärtslesbar oder durch Dual-Read abgesichert sein.

Fachlicher Vertrag: unverändert zu erhalten

  • Dateiinhalte, Attribute und Überschreibregeln sind bewusst festgelegt.
  • Ressourcen werden in allen Fehlerpfaden geschlossen.
  • Pfadvalidierung verhindert Traversal außerhalb erlaubter Wurzeln.

Hauptrisiko und Testfokus

resource handling, overwrite and atomicity

permissions, missing files, overwrite and large-file tests

Die Modernisierung gilt erst als abgeschlossen, wenn der fachliche Vertrag automatisiert belegt ist.

Verbindliches Code- und Rollenmapping

Die Zuordnung ist semantisch: Eine Legacy-Klasse kann in mehrere moderne Rollen zerlegt werden.

Legacy-Rolle / DateiModern-Rolle / DateiBedeutung
LegacyFileCopy.javaPathFileService.javaFile/Streams werden Path/Files und sichere Ressourcenverwaltung.

Legacy-Quellinventar

DateiTypAnnotationenöffentliche APIPatternZeilen
LegacyFileCopy.javaclass LegacyFileCopylong copy(File source, File target)Adapter – kapselt streambasiertes Kopieren hinter einer kleinen Datei-API.29

Modern-Quellinventar

DateiTypAnnotationenöffentliche APIPatternZeilen
PathFileService.javaclass PathFileServicelong copy(Path source, Path target)
List<Path> find(Path root, String suffix)
void zip(Path source, Path zip)
Adapter30

Dependency- und Laufzeitmigration

StatusDependencyVersionScopePrüfung
BEIBEHALTENorg.junit.jupiter:junit-jupiterBOM/Parent → BOM/Parenttest → testGemeinsame Dependency; Version und Scope im effektiven POM prüfen.
Direkte POM-Daten ersetzen keinen erfolgreichen Online-Build mit transitiver SBOM- und CVE-Prüfung.

Vorher-/Nachher-Codebelege

Die folgenden Ausschnitte stammen direkt aus den enthaltenen Projekten. Dadurch ist sichtbar, welche Verantwortung tatsächlich verschoben wurde.

Legacy
LegacyFileCopy.java
Modern
PathFileService.java

Migrationsbedeutung: File/Streams werden Path/Files und sichere Ressourcenverwaltung.

Legacy-Code

projects/17-io-nio/legacy/src/main/java/at/aydin/lab/io/legacy/LegacyFileCopy.java

package at.aydin.lab.io.legacy;

// Design Pattern: Adapter – kapselt streambasiertes Kopieren hinter einer kleinen Datei-API.
import java.io.*;

public final class LegacyFileCopy {
    public long copy(File source, File target) throws IOException {
        InputStream in = null;
        OutputStream out = null;
        long bytes = 0;
        try {
            in = new FileInputStream(source);
            out = new FileOutputStream(target);
            byte[] buffer = new byte[4096];
            int read;
            while ((read = in.read(buffer)) >= 0) {
                out.write(buffer, 0, read);
                bytes += read;
            }
            return bytes;
        } finally {
            if (in != null) try {
                in.close();
            } catch (IOException ignored) {
            }
            if (out != null) out.close();
        }
    }
}

Modern-Code

projects/17-io-nio/modern/src/main/java/at/aydin/lab/io/modern/PathFileService.java

package at.aydin.lab.io.modern;

import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.zip.*;

// Design Pattern: Adapter
// Zweck: Fachliche Dateioperationen werden hinter der modernen Path-/Files-API gebündelt.
public final class PathFileService {
    public long copy(Path source, Path target) throws IOException {
        Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
        return Files.size(target);
    }

    public List<Path> find(Path root, String suffix) throws IOException {
        try (var paths = Files.walk(root)) {
            return paths.filter(Files::isRegularFile).filter(p -> p.getFileName().toString().endsWith(suffix)).sorted()
                    .toList();
        }
    }

    public void zip(Path source, Path zip) throws IOException {
        try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(zip))) {
            out.putNextEntry(new ZipEntry(source.getFileName().toString()));
            Files.copy(source, out);
            out.closeEntry();
        }
    }
}
Technischen Unified Diff öffnen
--- LegacyFileCopy.java
+++ PathFileService.java
@@ -1,29 +1,30 @@
-package at.aydin.lab.io.legacy;
+package at.aydin.lab.io.modern;
 
-// Design Pattern: Adapter – kapselt streambasiertes Kopieren hinter einer kleinen Datei-API.
 import java.io.*;
+import java.nio.file.*;
+import java.util.*;
+import java.util.zip.*;
 
-public final class LegacyFileCopy {
-    public long copy(File source, File target) throws IOException {
-        InputStream in = null;
-        OutputStream out = null;
-        long bytes = 0;
-        try {
-            in = new FileInputStream(source);
-            out = new FileOutputStream(target);
-            byte[] buffer = new byte[4096];
-            int read;
-            while ((read = in.read(buffer)) >= 0) {
-                out.write(buffer, 0, read);
-                bytes += read;
-            }
-            return bytes;
-        } finally {
-            if (in != null) try {
-                in.close();
-            } catch (IOException ignored) {
-            }
-            if (out != null) out.close();
+// Design Pattern: Adapter
+// Zweck: Fachliche Dateioperationen werden hinter der modernen Path-/Files-API gebündelt.
+public final class PathFileService {
+    public long copy(Path source, Path target) throws IOException {
+        Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
+        return Files.size(target);
+    }
+
+    public List<Path> find(Path root, String suffix) throws IOException {
+        try (var paths = Files.walk(root)) {
+            return paths.filter(Files::isRegularFile).filter(p -> p.getFileName().toString().endsWith(suffix)).sorted()
+                    .toList();
+        }
+    }
+
+    public void zip(Path source, Path zip) throws IOException {
+        try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(zip))) {
+            out.putNextEntry(new ZipEntry(source.getFileName().toString()));
+            Files.copy(source, out);
+            out.closeEntry();
         }
     }
 }

Umsetzungsplan mit Qualitäts-Gates

  1. Arbeitspaket 1
    Legacy File-Verhalten inklusive Overwrite und Encoding testen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  2. Arbeitspaket 2
    String/File-Parameter auf Path an der Systemgrenze normalisieren. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  3. Arbeitspaket 3
    Files-Operationen mit expliziten CopyOptions einsetzen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  4. Arbeitspaket 4
    Temporärdatei/atomaren Move für kritische Schreibvorgänge prüfen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  5. Arbeitspaket 5
    Berechtigungs-, Symlink-, große Datei- und Fehlerfälle testen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  6. Arbeitspaket 6
    LegacyFileCopy nach Betriebsvergleich entfernen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.

Konkreter Test- und Abnahmekatalog

IDEbenePrüfungerforderlicher Nachweis
17-IO-NIO-A01Integration/ContractKopie ist byte-identisch.Automatisierter Test und CI-Protokoll
17-IO-NIO-A02Integration/ContractFehlende Quelle und bestehendes Ziel liefern definierte Fehler.Automatisierter Test und CI-Protokoll
17-IO-NIO-A03Integration/ContractKeine offenen File Descriptors.Automatisierter Test und CI-Protokoll
17-IO-NIO-A04Integration/ContractTraversal/Symlink-Risiken sind behandelt.Automatisierter Test und CI-Protokoll
17-IO-NIO-A05Integration/ContractGroße Dateien werden ohne unnötige Vollspeicherung verarbeitet.Automatisierter Test und CI-Protokoll
17-IO-NIO-T01UnitFachlogik ohne Container oder externen Dienst testen.Unit-Test
17-IO-NIO-T02RegressionLegacy- und Modern-Ergebnis für denselben Golden-Master-Vektor vergleichen.Vergleichsreport
17-IO-NIO-T03NegativeFehlerhafte, leere und grenzwertige Eingaben prüfen.Negativtest
17-IO-NIO-T04OperationsStart, Health, Shutdown und Konfigurationsfehler prüfen.Deployment-/Startprotokoll
17-IO-NIO-F01Fokuspermissions, missing files, overwrite and large-file testsModulspezifischer Testreport

Risikoregister des Moduls

RisikoAuswirkungGegenmaßnahmeGate
resource handling, overwrite and atomicityNIEDRIGpermissions, missing files, overwrite and large-file testsvor Cutover

Konfiguration und Ressourcen

Keine zusätzlichen Ressourcen.

Rollback und Koexistenz

PathFileService kann intern auf den Legacy-Pfad delegieren; Dateiformat und Zielpfad bleiben unverändert.

Abbruchkriterien

  • Fachlicher Golden-Master weicht ab.
  • Daten-, Nachrichten- oder API-Kompatibilität ist ungeklärt.
  • Fehlerquote, Latenz oder Ressourcenverbrauch überschreiten das vereinbarte Limit.
  • Monitoring oder Rückfallpfad ist nicht funktionsfähig.

Definition of Done

Direkte Arbeitslinks

⌂ Cockpit