EAR
Paket aus mehreren Modulen: WAR, EJB-JAR, Libraries und Deployment-Deskriptoren.
Klassische EAR/WAR/EJB-Anwendung mit Session Beans, JTA, JDBC/JPA, SOAP, JSP/JSF und serverseitigem Deployment.
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.
Paket aus mehreren Modulen: WAR, EJB-JAR, Libraries und Deployment-Deskriptoren.
Serverseitige Komponente mit Transaktion, Security, Pooling und Remoting.
Container-gesteuerte Transaktion ueber Datenbank, JMS oder weitere Ressourcen.
Namensdienst fuer DataSources, Queues und EJB-Referenzen.
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.
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
@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-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>
| Aspekt | Beschreibung |
|---|---|
| Fachliches Risiko | Unklare Verantwortung fuer Auftrag fuehrt zu widerspruechlichen Entscheidungen zwischen Alt- und Neusystem. |
| Technisches Risiko | EAR/WAR/EJB-JAR und angrenzende Komponenten werden isoliert betrachtet; Laufzeitkopplung bleibt verborgen. |
| Betriebsrisiko | Fehlerkanal, Monitoring, Restart oder manuelle Klaerung sind nicht ausreichend dokumentiert. |
| Migrationsrisiko | Neue Architektur uebernimmt Daten oder Schnittstellen, ohne fachliche Invarianten und historische Sonderfaelle abzusichern. |
| Pattern | Einsatz in diesem System |
|---|---|
| Strangler Fig Pattern | Neue Funktionalitaet vor das Altsystem setzen und Altanteile schrittweise herausloesen. |
| Anti-Corruption Layer | Altbegriffe, technische Codes und Datenformate vom neuen Domänenmodell trennen. |
| Facade | Komplexe Legacy-Operationen hinter klaren fachlichen Use-Case-Methoden kapseln. |
| Adapter | Protokolle und Formate wie SOAP, MQ, Copybook, SQL oder File in Ports uebersetzen. |
| Golden Master Test | Bestehendes Verhalten mit Referenzdaten erfassen und gegen neue Implementierung vergleichen. |
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.