Anwendungsserver · Prio 10 · Version 4

Java EE / WebSphere Monolith

Klassische EAR/WAR/EJB-Anwendung mit Session Beans, JTA, JDBC/JPA, SOAP, JSP/JSF und serverseitigem Deployment.

← Startseite
Kurzverständnis und Systemgrenze

Java-EE-Monolithen auf WebSphere, WebLogic oder JBoss enthalten haeufig ueber Jahre gewachsene technische Schichten: JSP/JSF, Struts, EJB Session Beans, DAOs, JPA, JDBC, SOAP-Clients, JMS und proprietaere Deployment-Deskriptoren.

Die groesste Gefahr liegt in unsichtbarer Kopplung. Eine scheinbar kleine Maske kann Session State, JTA-Transaktionen, Stored Procedures, JMS-Nachrichten und Host-Aufrufe beruehren. Ohne Laufzeitbeobachtung und Use-Case-Schnitt verschiebt man Risiken nur in neue Services.

Ein sinnvoller Modernisierungspfad beginnt mit Stabilisierung: Build reproduzierbar machen, Tests nachziehen, technische Adapter isolieren, Fachlogik aus UI/DAO-Schichten herausloesen und erst danach Module schneiden.

Daten- und Verantwortungsgrenze: Der Monolith besitzt oft Use-Case-Orchestrierung und transaktionale Konsistenz. Er kann Daten aus mehreren Quellen zusammenfuehren und ist deshalb nicht einfach durch viele kleine Services ersetzbar, solange Transaktionsgrenzen und fachliche Invarianten unklar sind.
Fachliche und technische Darstellung
Fachliche Sicht Java EE / WebSphere Monolith
Fachliche Sicht: Prozess, Verantwortung, Nachweis.
Technische Sicht Java EE / WebSphere Monolith
Technische Sicht: Komponenten, Protokolle, Betriebsbezug.
Wichtige Begriffe und Artefakte

EAR

Paket aus mehreren Modulen: WAR, EJB-JAR, Libraries und Deployment-Deskriptoren.

EJB Session Bean

Serverseitige Komponente mit Transaktion, Security, Pooling und Remoting.

JTA

Container-gesteuerte Transaktion ueber Datenbank, JMS oder weitere Ressourcen.

JNDI

Namensdienst fuer DataSources, Queues und EJB-Referenzen.

Typischer Ablauf Schritt für Schritt
  1. Webmaske sendet Auftrag an Servlet/JSF Controller.
  2. Controller ruft EJB-Facade mit fachlichem Command auf.
  3. EJB startet containerverwaltete JTA-Transaktion.
  4. Service schreibt DB, ruft Stored Procedure und sendet JMS-Ereignis.
  5. Bei Commit werden Daten und Nachricht konsistent sichtbar; bei Rollback muss alles zurueckfallen.
Ausführliche Praxisbeispiele mit Code und Konfiguration

Die Beispiele sind bewusst nicht minimalistisch. Sie zeigen typische Artefakte, die man in echten Legacy-Analysen findet: Schnittstellenverträge, Containerkonfiguration, SQL/PL-SQL, Jobdefinitionen, Queue-Regeln oder Adaptercode.

EAR-Struktur eines Legacy-Monolithen
billing-ear.ear
├── billing-web.war          # JSP/JSF/Servlet UI
├── billing-ejb.jar          # EJB Facades, Services, MDBs
├── billing-model.jar        # Entities, DTOs, alte Helper
├── lib/legacy-common.jar    # Querschnitt, oft stark gekoppelt
└── META-INF/application.xml # Modulverdrahtung
Stateless EJB mit JTA und Adaptergrenze
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class InvoiceUseCaseBean implements InvoiceUseCase {
    @EJB private CustomerRepository customerRepository;
    @EJB private InvoiceRepository invoiceRepository;
    @EJB private HostCreditCheckPort creditCheckPort;
    @Resource(mappedName = "jms/InvoiceQueue") private Queue invoiceQueue;
    @Inject private JMSContext jms;

    public InvoiceResult createInvoice(CreateInvoiceCommand command) {
        Customer customer = customerRepository.loadForUpdate(command.customerId());
        CreditDecision decision = creditCheckPort.check(customer, command.amount());
        if (!decision.accepted()) {
            return InvoiceResult.rejected(decision.reason());
        }
        Invoice invoice = invoiceRepository.create(customer, command.positions());
        jms.createProducer().setStringProperty("eventType", "InvoiceCreated").send(invoiceQueue, invoice.id());
        return InvoiceResult.created(invoice.id());
    }
}
persistence.xml mit Server-DataSource
<persistence-unit name="BillingPU" transaction-type="JTA">
  <jta-data-source>jdbc/BillingDS</jta-data-source>
  <class>com.example.billing.InvoiceEntity</class>
  <properties>
    <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle12cDialect"/>
    <property name="hibernate.show_sql" value="false"/>
  </properties>
</persistence-unit>
Risiken, Fehlerbilder und Diagnose
AspektBeschreibung
Fachliches RisikoUnklare Verantwortung fuer Auftrag fuehrt zu widerspruechlichen Entscheidungen zwischen Alt- und Neusystem.
Technisches RisikoEAR/WAR/EJB-JAR und angrenzende Komponenten werden isoliert betrachtet; Laufzeitkopplung bleibt verborgen.
BetriebsrisikoFehlerkanal, Monitoring, Restart oder manuelle Klaerung sind nicht ausreichend dokumentiert.
MigrationsrisikoNeue Architektur uebernimmt Daten oder Schnittstellen, ohne fachliche Invarianten und historische Sonderfaelle abzusichern.
Typische Fallen:
  • Fachlogik in JSP, Managed Beans, DAOs und Stored Procedures verteilt.
  • Transaktionen implizit durch Container gesteuert und im Code nicht sichtbar.
  • JNDI-Namen und Serverressourcen nur in WebSphere-Konfiguration dokumentiert.
  • Integrationstests fehlen, weil lokale Umgebung den Application Server nicht realistisch abbildet.
Modernisierungspfad und geeignete Entwurfsmuster
PatternEinsatz in diesem System
Strangler Fig PatternNeue Funktionalitaet vor das Altsystem setzen und Altanteile schrittweise herausloesen.
Anti-Corruption LayerAltbegriffe, technische Codes und Datenformate vom neuen Domänenmodell trennen.
FacadeKomplexe Legacy-Operationen hinter klaren fachlichen Use-Case-Methoden kapseln.
AdapterProtokolle und Formate wie SOAP, MQ, Copybook, SQL oder File in Ports uebersetzen.
Golden Master TestBestehendes Verhalten mit Referenzdaten erfassen und gegen neue Implementierung vergleichen.
Empfohlene Schritte:
  • Fuehre eine Application Service Facade ein, die Use Cases klar benennt.
  • Isoliere technische Adapter: Host, SOAP, MQ, DB, Files.
  • Erzeuge Characterization Tests und Golden-Master-Tests fuer kritische Workflows.
  • Migriere schrittweise auf modulare Architektur, nicht durch blindes Umschreiben von EJB zu REST.
Analysefragen für echte Projekte
  • Wer besitzt fachlich die Wahrheit fuer Auftrag?
  • Welche technische Komponente ist kritisch: EAR/WAR/EJB-JAR, EJB, JTA?
  • Welche Daten werden veraendert, gelesen, abgeleitet oder nur transportiert?
  • Welche Fehler sind fachlich erwartbar und welche sind technische Stoerungen?
  • Welche Protokolle, Dateien, Tabellen, Queues oder Reports bilden den offiziellen Vertrag?
  • Wie wird ein Fehler heute erkannt, korrigiert und gegenueber dem Fachbereich nachgewiesen?
  • Welche Teile lassen sich lesend modernisieren und welche sind schreibend hochkritisch?
  • Welche Tests sichern aktuelles Verhalten, bevor Refactoring oder Migration beginnt?
Übung

Waehle einen Monolith-Use-Case und zeichne alle Schichten von UI bis Datenbank. Markiere, wo Transaktion beginnt, welche Ressourcen beteiligt sind, welche fachlichen Regeln verteilt sind und welcher Teil als erstes in eine moderne Facade gekapselt werden kann.

⌂ Cockpit