10 Java Enterprise Migration auf OpenShift
Legacy-Java-Systeme sollten selten per Big Bang migriert werden. Besser ist fachliches Schneiden, Adapter, Contract Tests, Strangler Fig und schrittweise Containerisierung.
Ausgangslage
Typische Legacy-Landschaft: WebSphere Traditional, Java 8, EAR, EJB, SOAP, JMS, JTA, JSP/JSF, Oracle, Stored Procedures und Batchjobs.
OpenShift löst diese fachliche Komplexität nicht automatisch. Es liefert aber eine Plattform, um Teile kontrolliert neu zu bauen, zu betreiben und zu messen.
Migrationsstrategie
Lift and Shift nur als Zwischenstufe, wenn Risiko reduziert und Betrieb stabilisiert wird.
Strangler Fig: neue fachliche Funktionen werden vor das Alt-System gesetzt und schrittweise herausgeschnitten.
Adapter Pattern schützt neue Domäne vor alten SOAP-/DTO-/Datenbankmodellen.
Contract Tests sichern Schnittstellen, bevor Traffic umgeschaltet wird.
Java Runtime Entscheidung
Spring Boot: große Ökosystembreite, viele Enterprise-Teams kennen es.
Quarkus: containerfreundlich, schnelle Starts, geringer Speicherbedarf, gute Kubernetes-/OpenShift-Integration.
Jakarta EE/MicroProfile: gute Wahl, wenn Standards und App-Server-Nähe wichtig sind.
Ausführliches Enterprise-Beispiel
Das Beispiel folgt einer fiktiven Shop-Landschaft mit order-api, billing-api, payment-api, portal-ui, Batch-Export und Messaging. Der Fokus liegt auf sauberem Verständnis statt auf blindem Kopieren.
Fachlicher Ablauf
- Kunde bestellt über Portal.
- order-api validiert Auftrag.
- billing-api erzeugt Rechnung.
- payment-api prüft Zahlung.
- Events informieren Lager und Reporting.
Technischer Ablauf
- Route nimmt HTTPS an.
- Service verteilt auf Pods.
- Pods lesen ConfigMaps und Secrets.
- Readiness schützt Rollout.
- Monitoring misst Fehlerquote und Latenz.
Konfigurations- und Codebeispiele
JAVA
// Pattern: Adapter - kapselt altes SOAP-Modell hinter moderner Domänenschnittstelle.
// Pattern: Circuit Breaker - verhindert Kaskadenausfälle bei instabilem Legacy-System.
public final class LegacyBillingAdapter implements BillingPort {
private final SoapBillingClient soapClient;
private final CircuitBreaker circuitBreaker;
public LegacyBillingAdapter(SoapBillingClient soapClient, CircuitBreaker circuitBreaker) {
this.soapClient = soapClient;
this.circuitBreaker = circuitBreaker;
}
@Override
public Invoice createInvoice(Order order) {
return circuitBreaker.executeSupplier(() -> {
LegacyInvoiceRequest request = LegacyInvoiceMapper.fromDomain(order);
LegacyInvoiceResponse response = soapClient.createInvoice(request);
return LegacyInvoiceMapper.toDomain(response);
});
}
}
DOCKER
FROM registry.access.redhat.com/ubi9/openjdk-21-runtime:latest
WORKDIR /deployments
COPY target/quarkus-app/lib/ ./lib/
COPY target/quarkus-app/*.jar ./
COPY target/quarkus-app/app/ ./app/
COPY target/quarkus-app/quarkus/ ./quarkus/
ENV JAVA_OPTS="-XX:MaxRAMPercentage=75.0 -XX:+ExitOnOutOfMemoryError"
EXPOSE 8080
USER 185
CMD ["java", "-jar", "quarkus-run.jar"]
YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-api
labels:
app: order-api
spec:
replicas: 3
selector:
matchLabels:
app: order-api
template:
metadata:
labels:
app: order-api
spec:
serviceAccountName: order-api-sa
containers:
- name: order-api
image: image-registry.openshift-image-registry.svc:5000/shop/order-api:1.0.0
ports:
- containerPort: 8080
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1024Mi
readinessProbe:
httpGet:
path: /q/health/ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
livenessProbe:
httpGet:
path: /q/health/live
port: 8080
initialDelaySeconds: 30
periodSeconds: 20
Typische Fehlerbilder und Diagnose
Pending Pods
Prüfe Ressourcen, Node-Selector, Taints, PVC und Quotas. Nicht sofort am Java-Code suchen.
CrashLoopBackOff
Prüfe Logs des vorherigen Containers, Config/Secrets, Port, JVM Memory und Health Endpoints.
Route erreichbar, App nicht
Prüfe Service-Selector, Endpoints, Readiness, TLS-Termination und NetworkPolicy.
Praxisaufgabe
Wähle eine Legacy-Funktion, etwa Rechnung erzeugen. Schneide sie fachlich, erstelle Adapter, Contract Test, neues REST-API und eine Route. Leite erst 5 Prozent Traffic um.
Merksätze
- Deklarativer Zustand ist wichtiger als manuelle Serveränderung.
- Security und Betrieb gehören von Anfang an zum Deployment.
- Jede YAML-Datei ist Architekturentscheidung und sollte reviewbar sein.
- Produktionsreife entsteht durch Messbarkeit, Rollback und klare Ownership.