Modul 11 · Migration Deep Dive · Stufe 2 Java Core

Java-Grundlagen

mutable JavaBean und Hilfsklassen wird nachvollziehbar in Records, Pattern Matching und Value Objects überführt. Die Akte zeigt nicht nur das Ziel, sondern die tatsächlichen Dateien, APIs, Dependencies, Codebelege, Tests, Risiken und Cutover-Schritte.

JavaBeanValue ObjectRecord
2 → 3Produktionsdateien
53 → 30Java-Zeilen
1 → 1Testdateien
0 / 0Dependencies entfernt / neu
NIEDRIGRisiko · Score 1

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 API8 erkannte Methoden2 erkannte MethodenMethoden werden nach fachlicher Rolle gemappt; reine Bootstrap- und Framework-Methoden sind kein fachlicher Vertrag.
Datenmodellclass BasicsLegacyApplication, class LegacyCustomerclass BasicsModernApplication, enum CustomerStatus, record CustomerFeldnamen, 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

  • Gleichheit, Hashing und String-Repräsentation werden bewusst definiert.
  • Records bleiben echte Value Objects ohne versteckte Mutable State.
  • Serialisierung wird bei extern verwendeten Modellen explizit geprüft.

Hauptrisiko und Testfokus

serialization/equality behavior changes

equals/hashCode, validation and immutability 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
LegacyCustomer.javaCustomer.java + CustomerStatus.javaMutable Bean wird Record plus typisierter Status.
BasicsLegacyApplication.javaBasicsModernApplication.javaAufrufer wird auf Value Semantics umgestellt.

Legacy-Quellinventar

DateiTypAnnotationenöffentliche APIPatternZeilen
BasicsLegacyApplication.javaclass BasicsLegacyApplicationvoid main(String[] args)14
LegacyCustomer.javaclass LegacyCustomerlong getId()
void setId(long id)
String getName()
void setName(String name)
String getStatus()
void setStatus(String status)
String displayText()
JavaBean39

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
LegacyCustomer.java
Modern
Customer.java + CustomerStatus.java

Migrationsbedeutung: Mutable Bean wird Record plus typisierter Status.

Legacy-Code

projects/11-java-basics/legacy/src/main/java/at/aydin/lab/basics/legacy/LegacyCustomer.java

package at.aydin.lab.basics.legacy;

// Design Pattern: JavaBean
// Zweck: Historische mutable Datenstruktur mit leerem Konstruktor und Settern.
public class LegacyCustomer {
    private long id;
    private String name;
    private String status;
    public LegacyCustomer() {
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String displayText() {
        return id + ": " + name + " [" + status + "]";
    }
}

Modern-Code

projects/11-java-basics/modern/src/main/java/at/aydin/lab/basics/modern/Customer.java

package at.aydin.lab.basics.modern;

// Design Pattern: Value Object
// Zweck: Unveränderliche, validierte fachliche Daten mit wertbasierter Gleichheit.
public record Customer(long id, String name, CustomerStatus status) {
    public Customer {
        if (id <= 0) throw new IllegalArgumentException("id muss positiv sein");
        if (name == null || name.isBlank()) throw new IllegalArgumentException("name fehlt");
        if (status == null) throw new IllegalArgumentException("status fehlt");
    }

    public String displayText() {
        return "%d: %s [%s]".formatted(id, name, status);
    }
}

Modern-Code

projects/11-java-basics/modern/src/main/java/at/aydin/lab/basics/modern/CustomerStatus.java

package at.aydin.lab.basics.modern;

public enum CustomerStatus {
    ACTIVE, INACTIVE
}
Legacy
BasicsLegacyApplication.java
Modern
BasicsModernApplication.java

Migrationsbedeutung: Aufrufer wird auf Value Semantics umgestellt.

Legacy-Code

projects/11-java-basics/legacy/src/main/java/at/aydin/lab/basics/legacy/BasicsLegacyApplication.java

package at.aydin.lab.basics.legacy;

public final class BasicsLegacyApplication {
    private BasicsLegacyApplication() {
    }

    public static void main(String[] args) {
        LegacyCustomer customer = new LegacyCustomer();
        customer.setId(42L);
        customer.setName("Aydin");
        customer.setStatus("ACTIVE");
        System.out.println(customer.displayText());
    }
}

Modern-Code

projects/11-java-basics/modern/src/main/java/at/aydin/lab/basics/modern/BasicsModernApplication.java

package at.aydin.lab.basics.modern;

public final class BasicsModernApplication {
    private BasicsModernApplication() {
    }

    public static void main(String[] args) {
        System.out.println(new Customer(42, "Aydin", CustomerStatus.ACTIVE).displayText());
    }
}
Technischen Unified Diff öffnen
--- BasicsLegacyApplication.java
+++ BasicsModernApplication.java
@@ -1,14 +1,10 @@
-package at.aydin.lab.basics.legacy;
+package at.aydin.lab.basics.modern;
 
-public final class BasicsLegacyApplication {
-    private BasicsLegacyApplication() {
+public final class BasicsModernApplication {
+    private BasicsModernApplication() {
     }
 
     public static void main(String[] args) {
-        LegacyCustomer customer = new LegacyCustomer();
-        customer.setId(42L);
-        customer.setName("Aydin");
-        customer.setStatus("ACTIVE");
-        System.out.println(customer.displayText());
+        System.out.println(new Customer(42, "Aydin", CustomerStatus.ACTIVE).displayText());
     }
 }

Umsetzungsplan mit Qualitäts-Gates

  1. Arbeitspaket 1
    Bean-Eigenschaften, Nullregeln und Mutationen inventarisieren. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  2. Arbeitspaket 2
    Customer als Record nur dort einsetzen, wo Wertsemantik passt. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  3. Arbeitspaket 3
    Status-Strings durch CustomerStatus mit stabiler externer Repräsentation ersetzen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  4. Arbeitspaket 4
    Adapter für Bean-basierte Frameworks oder Mapper ergänzen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  5. Arbeitspaket 5
    Equals/hashCode- und JSON/XML-Verhalten vergleichen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  6. Arbeitspaket 6
    Mutable Bean erst entfernen, wenn alle Integrationen angepasst sind. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.

Konkreter Test- und Abnahmekatalog

IDEbenePrüfungerforderlicher Nachweis
11-JAVA-BASICS-A01Integration/ContractWertegleichheit entspricht fachlicher Erwartung.Automatisierter Test und CI-Protokoll
11-JAVA-BASICS-A02Integration/ContractKeine Mutation nach Konstruktion möglich.Automatisierter Test und CI-Protokoll
11-JAVA-BASICS-A03Integration/ContractPersistenz-/Serialisierungsframeworks können den Typ verarbeiten.Automatisierter Test und CI-Protokoll
11-JAVA-BASICS-A04Integration/ContractStatuswerte sind versionierbar.Automatisierter Test und CI-Protokoll
11-JAVA-BASICS-A05Integration/ContractNull- und Validierungsregeln sind getestet.Automatisierter Test und CI-Protokoll
11-JAVA-BASICS-T01UnitFachlogik ohne Container oder externen Dienst testen.Unit-Test
11-JAVA-BASICS-T02RegressionLegacy- und Modern-Ergebnis für denselben Golden-Master-Vektor vergleichen.Vergleichsreport
11-JAVA-BASICS-T03NegativeFehlerhafte, leere und grenzwertige Eingaben prüfen.Negativtest
11-JAVA-BASICS-T04OperationsStart, Health, Shutdown und Konfigurationsfehler prüfen.Deployment-/Startprotokoll
11-JAVA-BASICS-F01Fokusequals/hashCode, validation and immutability testsModulspezifischer Testreport

Risikoregister des Moduls

RisikoAuswirkungGegenmaßnahmeGate
serialization/equality behavior changesNIEDRIGequals/hashCode, validation and immutability testsvor Cutover

Konfiguration und Ressourcen

Keine zusätzlichen Ressourcen.

Rollback und Koexistenz

Ein Mapper zwischen LegacyCustomer und Customer erlaubt schrittweise Umstellung ohne gleichzeitige Änderung aller Aufrufer.

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