Modul 33 · Migration Deep Dive · Stufe 3 Application Layer

SMTP und Mail

javax.mail MimeMessage wird nachvollziehbar in Jakarta Mail und Mail Gateway überführt. Die Akte zeigt nicht nur das Ziel, sondern die tatsächlichen Dateien, APIs, Dependencies, Codebelege, Tests, Risiken und Cutover-Schritte.

GatewayBuilder
1 → 2Produktionsdateien
18 → 33Java-Zeilen
1 → 1Testdateien
1 / 1Dependencies 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ängigkeiten2 direkte Dependencies2 direkte Dependencies1 neu, 1 entfernt; Versionen und transitive Auswirkungen im erfolgreichen Online-Build prüfen.
Öffentliche API1 erkannte Methoden2 erkannte MethodenMethoden werden nach fachlicher Rolle gemappt; reine Bootstrap- und Framework-Methoden sind kein fachlicher Vertrag.
Datenmodellclass LegacyMailFactoryclass JakartaMailGateway, record MailCommandFeldnamen, 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 KonfigurationParallelbetrieb, Replay/Retry und Rückrouting müssen vor Abschaltung des Legacy-Pfads erprobt sein.
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

  • Absender, Empfänger, Betreff, Body und Charset bleiben kompatibel.
  • Header Injection wird verhindert.
  • Transportfehler sind wiederholbar und nachvollziehbar.

Hauptrisiko und Testfokus

header injection, transport errors and charset drift

recipient validation, Unicode, transport failure and header 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
LegacyMailFactory.javaMailCommand.java + JakartaMailGateway.javaMessage-Erzeugung wird validiertes Kommando plus Gateway.

Legacy-Quellinventar

DateiTypAnnotationenöffentliche APIPatternZeilen
LegacyMailFactory.javaclass LegacyMailFactoryMimeMessage create(String from, String to, String subject, String body)Factory – erzeugt vorkonfigurierte MimeMessage-Objekte.18

Modern-Quellinventar

DateiTypAnnotationenöffentliche APIPatternZeilen
JakartaMailGateway.javaclass JakartaMailGatewayMimeMessage prepare(MailCommand c)
void send(MailCommand c)
Gateway27
MailCommand.javarecord MailCommandCommand6

Dependency- und Laufzeitmigration

StatusDependencyVersionScopePrüfung
ENTFERNTcom.sun.mail:javax.mail1.6.2compileLegacy-Laufzeit entfällt oder wird durch Plattform/BOM ersetzt.
NEUorg.eclipse.angus:jakarta.mail2.0.3compileNeue Laufzeit-/Testabhängigkeit; transitiv, lizenz- und security-seitig prüfen.
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
LegacyMailFactory.java
Modern
MailCommand.java + JakartaMailGateway.java

Migrationsbedeutung: Message-Erzeugung wird validiertes Kommando plus Gateway.

Legacy-Code

projects/33-smtp-mail/legacy/src/main/java/at/aydin/lab/mail/legacy/LegacyMailFactory.java

package at.aydin.lab.mail.legacy;

// Design Pattern: Factory – erzeugt vorkonfigurierte MimeMessage-Objekte.
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

public final class LegacyMailFactory {
    public MimeMessage create(String from, String to, String subject, String body) throws Exception {
        Session session = Session.getDefaultInstance(new Properties());
        MimeMessage m = new MimeMessage(session);
        m.setFrom(new InternetAddress(from));
        m.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
        m.setSubject(subject, "UTF-8");
        m.setText(body, "UTF-8");
        return m;
    }
}

Modern-Code

projects/33-smtp-mail/modern/src/main/java/at/aydin/lab/mail/modern/MailCommand.java

package at.aydin.lab.mail.modern;

// Design Pattern: Command
// Zweck: Vollständiger Versandauftrag wird als unveränderliches Objekt übergeben.
public record MailCommand(String from, String to, String subject, String body) {
}

Modern-Code

projects/33-smtp-mail/modern/src/main/java/at/aydin/lab/mail/modern/JakartaMailGateway.java

package at.aydin.lab.mail.modern;

import jakarta.mail.*;
import jakarta.mail.internet.*;
import java.util.*;

// Design Pattern: Gateway
// Zweck: Jakarta-Mail-API bleibt außerhalb des fachlichen Aufrufers.
public final class JakartaMailGateway {
    private final Session session;
    public JakartaMailGateway(Properties properties) {
        session = Session.getInstance(properties);
    }

    public MimeMessage prepare(MailCommand c) throws Exception {
        MimeMessage m = new MimeMessage(session);
        m.setFrom(new InternetAddress(c.from()));
        m.setRecipient(Message.RecipientType.TO, new InternetAddress(c.to()));
        m.setSubject(c.subject(), "UTF-8");
        m.setText(c.body(), "UTF-8");
        return m;
    }

    public void send(MailCommand c) throws Exception {
        Transport.send(prepare(c));
    }
}

Umsetzungsplan mit Qualitäts-Gates

  1. Arbeitspaket 1
    Legacy MimeMessage-Felder und Session-Eigenschaften inventarisieren. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  2. Arbeitspaket 2
    MailCommand als validiertes Fachkommando definieren. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  3. Arbeitspaket 3
    JakartaMailGateway als Infrastrukturadapter implementieren. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  4. Arbeitspaket 4
    Unicode, Multipart/Attachments und Reply-To prüfen, soweit verwendet. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  5. Arbeitspaket 5
    Timeout-, Auth-, TLS- und Fehlerbehandlung konfigurieren. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  6. Arbeitspaket 6
    javax.mail-Pfad nach Testmail-/Sandbox-Abnahme entfernen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.

Konkreter Test- und Abnahmekatalog

IDEbenePrüfungerforderlicher Nachweis
33-SMTP-MAIL-A01Integration/ContractUnicode-Inhalte kommen korrekt an.Automatisierter Test und CI-Protokoll
33-SMTP-MAIL-A02Integration/ContractCR/LF in Headerfeldern wird abgewiesen.Automatisierter Test und CI-Protokoll
33-SMTP-MAIL-A03Integration/ContractTransportfehler enthalten Empfänger-/Correlation-Kontext ohne Body-Leak.Automatisierter Test und CI-Protokoll
33-SMTP-MAIL-A04Integration/ContractTLS/Auth-Konfiguration ist externisiert.Automatisierter Test und CI-Protokoll
33-SMTP-MAIL-A05Integration/ContractKeine javax.mail-Imports im Modern-Modul.Automatisierter Test und CI-Protokoll
33-SMTP-MAIL-T01UnitFachlogik ohne Container oder externen Dienst testen.Unit-Test
33-SMTP-MAIL-T02RegressionLegacy- und Modern-Ergebnis für denselben Golden-Master-Vektor vergleichen.Vergleichsreport
33-SMTP-MAIL-T03NegativeFehlerhafte, leere und grenzwertige Eingaben prüfen.Negativtest
33-SMTP-MAIL-T04OperationsStart, Health, Shutdown und Konfigurationsfehler prüfen.Deployment-/Startprotokoll
33-SMTP-MAIL-T05ContractProtokoll, Status/Headers, Payload und Timeout gegen Consumer Contract prüfen.Contract-Test
33-SMTP-MAIL-F01Fokusrecipient validation, Unicode, transport failure and header testsModulspezifischer Testreport

Risikoregister des Moduls

RisikoAuswirkungGegenmaßnahmeGate
header injection, transport errors and charset driftNIEDRIGrecipient validation, Unicode, transport failure and header testsvor Cutover
Neue Framework-/Library-LaufzeitabhängigkeitenMITTELSBOM, Lizenz-, CVE- und transitive Dependency-Prüfung im Online-Buildvor Release
Legacy-Verhalten war implizit an entfernte Library gekoppeltMITTELContract-/Golden-Master-Tests und gezielte Fehlerpfadevor Abschaltung

Konfiguration und Ressourcen

Keine zusätzlichen Ressourcen.

Rollback und Koexistenz

MailCommand bleibt stabil; ein LegacyMailAdapter kann temporär denselben Command über javax.mail senden.

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