Modul 27 · Migration Deep Dive · Stufe 5 Enterprise Runtime

EJB und Services

EJB-2-artige Home/Remote-Schnittstellen wird nachvollziehbar in Spring Service und REST Facade überführt. Die Akte zeigt nicht nur das Ziel, sondern die tatsächlichen Dateien, APIs, Dependencies, Codebelege, Tests, Risiken und Cutover-Schritte.

Session FacadeRemote Facade
3 → 3Produktionsdateien
44 → 41Java-Zeilen
1 → 1Testdateien
2 / 2Dependencies entfernt / neu
NIEDRIGRisiko · Score 1

Was sich konkret ändert

DimensionLegacyModernMigrationskonsequenz
Programmiermodellimperativ / ohne Framework-AnnotationenPostMapping, RequestMapping, RequestParam, RestController, Service, SpringBootApplicationAnnotationen und Containerfunktionen werden nur dort eingesetzt, wo sie eine konkrete technische Verantwortung übernehmen.
Abhängigkeiten2 direkte Dependencies2 direkte Dependencies2 neu, 2 entfernt; Versionen und transitive Auswirkungen im erfolgreichen Online-Build prüfen.
Öffentliche API6 erkannte Methoden3 erkannte MethodenMethoden werden nach fachlicher Rolle gemappt; reine Bootstrap- und Framework-Methoden sind kein fachlicher Vertrag.
Datenmodellclass OrderSessionBean, interface OrderHome, interface OrderRemoteclass OrderApplication, class OrderController, class OrderServiceFeldnamen, 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 KonfigurationStartup, Lifecycle, Security Context und Remote-/Containerfehler separat testen.
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

  • Servicevertrag, Transaktions- und Security-Semantik bleiben explizit.
  • Remote-Ausnahmen werden stabil auf HTTP/Fachfehler abgebildet.
  • Geschäftslogik bleibt im Service, nicht im Controller.

Hauptrisiko und Testfokus

transaction/security semantics and remote contract drift

service contract, web adapter and transaction 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
OrderHome.java + OrderRemote.javaOrderController.javaRemote EJB Contract wird HTTP Remote Facade.
OrderSessionBean.javaOrderService.javaSession Bean wird containerarmer Service.
EJB Container BootstrapOrderApplication.javaDeploymentmodell wechselt zu Spring Boot.

Legacy-Quellinventar

DateiTypAnnotationenöffentliche APIPatternZeilen
OrderHome.javainterface OrderHome8
OrderRemote.javainterface OrderRemoteRemote Facade10
OrderSessionBean.javaclass OrderSessionBeanString placeOrder(String sku, int quantity)
void ejbCreate()
void ejbActivate()
void ejbPassivate()
void ejbRemove()
void setSessionContext(SessionContext context)
Session Facade26

Modern-Quellinventar

DateiTypAnnotationenöffentliche APIPatternZeilen
OrderApplication.javaclass OrderApplicationSpringBootApplicationvoid main(String[] args)11
OrderController.javaclass OrderControllerPostMapping, RequestMapping, RequestParam, RestControllerString order(@RequestParam String sku, @RequestParam int quantity)17
OrderService.javaclass OrderServiceServiceString placeOrder(String sku, int quantity)Service Layer13

Dependency- und Laufzeitmigration

StatusDependencyVersionScopePrüfung
ENTFERNTjavax.ejb:javax.ejb-api3.2.2compileLegacy-Laufzeit entfällt oder wird durch Plattform/BOM ersetzt.
ENTFERNTorg.junit.jupiter:junit-jupiterBOM/ParenttestLegacy-Laufzeit entfällt oder wird durch Plattform/BOM ersetzt.
NEUorg.springframework.boot:spring-boot-starter-testBOM/ParenttestNeue Laufzeit-/Testabhängigkeit; transitiv, lizenz- und security-seitig prüfen.
NEUorg.springframework.boot:spring-boot-starter-webBOM/ParentcompileNeue Laufzeit-/Testabhängigkeit; transitiv, lizenz- und security-seitig 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
OrderHome.java + OrderRemote.java
Modern
OrderController.java

Migrationsbedeutung: Remote EJB Contract wird HTTP Remote Facade.

Legacy-Code

projects/27-ejb-services/legacy/src/main/java/at/aydin/lab/ejb/legacy/OrderHome.java

package at.aydin.lab.ejb.legacy;

import javax.ejb.*;
import java.rmi.RemoteException;

public interface OrderHome extends EJBHome {
    OrderRemote create() throws CreateException, RemoteException;
}

Legacy-Code

projects/27-ejb-services/legacy/src/main/java/at/aydin/lab/ejb/legacy/OrderRemote.java

package at.aydin.lab.ejb.legacy;

import javax.ejb.EJBObject;
import java.rmi.RemoteException;

// Design Pattern: Remote Facade
// Zweck: Grobgranulare Remote-Schnittstelle reduziert verteilte Einzelaufrufe.
public interface OrderRemote extends EJBObject {
    String placeOrder(String sku, int quantity) throws RemoteException;
}

Modern-Code

projects/27-ejb-services/modern/src/main/java/at/aydin/lab/ejb/modern/OrderController.java

package at.aydin.lab.ejb.modern;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/orders")
public class OrderController {
    private final OrderService service;
    public OrderController(OrderService service) {
        this.service = service;
    }

    @PostMapping
    public String order(@RequestParam String sku, @RequestParam int quantity) {
        return service.placeOrder(sku, quantity);
    }
}
Legacy
OrderSessionBean.java
Modern
OrderService.java

Migrationsbedeutung: Session Bean wird containerarmer Service.

Legacy-Code

projects/27-ejb-services/legacy/src/main/java/at/aydin/lab/ejb/legacy/OrderSessionBean.java

package at.aydin.lab.ejb.legacy;

import javax.ejb.*;

// Design Pattern: Session Facade
// Zweck: Bündelt fachlichen Bestellablauf in einer serverseitigen Session-Komponente.
public class OrderSessionBean implements SessionBean {
    public String placeOrder(String sku, int quantity) {
        return "ORDERED " + quantity + " x " + sku;
    }

    public void ejbCreate() {
    }

    public void ejbActivate() {
    }

    public void ejbPassivate() {
    }

    public void ejbRemove() {
    }

    public void setSessionContext(SessionContext context) {
    }
}

Modern-Code

projects/27-ejb-services/modern/src/main/java/at/aydin/lab/ejb/modern/OrderService.java

package at.aydin.lab.ejb.modern;

import org.springframework.stereotype.Service;

// Design Pattern: Service Layer
// Zweck: Fachlogik ist containerleicht, lokal testbar und nicht an RemoteObject gebunden.
@Service
public class OrderService {
    public String placeOrder(String sku, int quantity) {
        if (quantity <= 0) throw new IllegalArgumentException("quantity");
        return "ORDERED " + quantity + " x " + sku;
    }
}
Technischen Unified Diff öffnen
--- OrderSessionBean.java
+++ OrderService.java
@@ -1,26 +1,13 @@
-package at.aydin.lab.ejb.legacy;
+package at.aydin.lab.ejb.modern;
 
-import javax.ejb.*;
+import org.springframework.stereotype.Service;
 
-// Design Pattern: Session Facade
-// Zweck: Bündelt fachlichen Bestellablauf in einer serverseitigen Session-Komponente.
-public class OrderSessionBean implements SessionBean {
+// Design Pattern: Service Layer
+// Zweck: Fachlogik ist containerleicht, lokal testbar und nicht an RemoteObject gebunden.
+@Service
+public class OrderService {
     public String placeOrder(String sku, int quantity) {
+        if (quantity <= 0) throw new IllegalArgumentException("quantity");
         return "ORDERED " + quantity + " x " + sku;
     }
-
-    public void ejbCreate() {
-    }
-
-    public void ejbActivate() {
-    }
-
-    public void ejbPassivate() {
-    }
-
-    public void ejbRemove() {
-    }
-
-    public void setSessionContext(SessionContext context) {
-    }
 }
Legacy
EJB Container Bootstrap
Modern
OrderApplication.java

Migrationsbedeutung: Deploymentmodell wechselt zu Spring Boot.

Legacy-Code

projects/27-ejb-services/legacy/src/main/java/at/aydin/lab/ejb/legacy/OrderSessionBean.java

package at.aydin.lab.ejb.legacy;

import javax.ejb.*;

// Design Pattern: Session Facade
// Zweck: Bündelt fachlichen Bestellablauf in einer serverseitigen Session-Komponente.
public class OrderSessionBean implements SessionBean {
    public String placeOrder(String sku, int quantity) {
        return "ORDERED " + quantity + " x " + sku;
    }

    public void ejbCreate() {
    }

    public void ejbActivate() {
    }

    public void ejbPassivate() {
    }

    public void ejbRemove() {
    }

    public void setSessionContext(SessionContext context) {
    }
}

Modern-Code

projects/27-ejb-services/modern/src/main/java/at/aydin/lab/ejb/modern/OrderApplication.java

package at.aydin.lab.ejb.modern;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}
Technischen Unified Diff öffnen
--- OrderSessionBean.java
+++ OrderApplication.java
@@ -1,26 +1,11 @@
-package at.aydin.lab.ejb.legacy;
+package at.aydin.lab.ejb.modern;
 
-import javax.ejb.*;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
 
-// Design Pattern: Session Facade
-// Zweck: Bündelt fachlichen Bestellablauf in einer serverseitigen Session-Komponente.
-public class OrderSessionBean implements SessionBean {
-    public String placeOrder(String sku, int quantity) {
-        return "ORDERED " + quantity + " x " + sku;
-    }
-
-    public void ejbCreate() {
-    }
-
-    public void ejbActivate() {
-    }
-
-    public void ejbPassivate() {
-    }
-
-    public void ejbRemove() {
-    }
-
-    public void setSessionContext(SessionContext context) {
+@SpringBootApplication
+public class OrderApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(OrderApplication.class, args);
     }
 }

Umsetzungsplan mit Qualitäts-Gates

  1. Arbeitspaket 1
    Home/Remote-Verträge und Container-Services inventarisieren. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  2. Arbeitspaket 2
    OrderService als containerunabhängige Session Facade extrahieren. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  3. Arbeitspaket 3
    Transaktion und Security explizit über Spring-Konfiguration/Annotationen nachbilden. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  4. Arbeitspaket 4
    OrderController als Remote Facade mit versioniertem Vertrag einführen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  5. Arbeitspaket 5
    Client-Adapter und Contract-Tests für beide Endpunkte erstellen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  6. Arbeitspaket 6
    EJB erst nach Consumer- und Betriebsfreigabe abschalten. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.

Konkreter Test- und Abnahmekatalog

IDEbenePrüfungerforderlicher Nachweis
27-EJB-SERVICES-A01Integration/ContractFachresultate stimmen zwischen EJB und Service überein.Automatisierter Test und CI-Protokoll
27-EJB-SERVICES-A02Integration/ContractTransaktionsrollback entspricht bisheriger Semantik.Automatisierter Test und CI-Protokoll
27-EJB-SERVICES-A03Integration/ContractSecurity-Entscheidungen sind mindestens gleich streng.Automatisierter Test und CI-Protokoll
27-EJB-SERVICES-A04Integration/ContractHTTP-Fehlerabbildung ist dokumentiert.Automatisierter Test und CI-Protokoll
27-EJB-SERVICES-A05Integration/ContractKeine EJB-API in der Fachlogik.Automatisierter Test und CI-Protokoll
27-EJB-SERVICES-T01UnitFachlogik ohne Container oder externen Dienst testen.Unit-Test
27-EJB-SERVICES-T02RegressionLegacy- und Modern-Ergebnis für denselben Golden-Master-Vektor vergleichen.Vergleichsreport
27-EJB-SERVICES-T03NegativeFehlerhafte, leere und grenzwertige Eingaben prüfen.Negativtest
27-EJB-SERVICES-T04OperationsStart, Health, Shutdown und Konfigurationsfehler prüfen.Deployment-/Startprotokoll
27-EJB-SERVICES-T05LifecycleContainer-/Service-Lifecycle, Startup-Fehler und Recovery prüfen.Runtime-Test
27-EJB-SERVICES-F01Fokusservice contract, web adapter and transaction testsModulspezifischer Testreport

Risikoregister des Moduls

RisikoAuswirkungGegenmaßnahmeGate
transaction/security semantics and remote contract driftNIEDRIGservice contract, web adapter and transaction 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

REST Facade kann intern auf den EJB-Adapter delegieren; externe Umschaltung erfolgt unabhängig von der schrittweisen Fachlogikmigration.

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