Enterprise Java Verständnis Lehrbuch V6

HTML-Fassung zur Markdown-Datei deep-learning-spur/06-v6-final-praxislabor/markdown/enterprise-java-lehrbuch-v6.md

#Enterprise Java Verständnis Lehrbuch V6

Stand: 2026-07-07

#Inhaltsverzeichnis


#01. Enterprise Java V6

Warum Enterprise Java mehr ist als eine Sammlung von Frameworks.

#Was Enterprise Java bedeutet

Enterprise Java ist die Fähigkeit, fachliche Abläufe, technische Laufzeitumgebungen, Datenhaltung, Integration, Sicherheit, Betrieb und Änderbarkeit gemeinsam zu beherrschen. Ein Senior-Entwickler denkt nicht nur in Klassen, sondern in Verträgen, Grenzen, Lebenszyklen, Fehlerszenarien und betrieblichen Nachweisen.

#Fachliche und technische Sicht trennen

Eine typische Fehlerquelle in Enterprise-Projekten ist, dass technische Begriffe die fachlichen Begriffe verdrängen. Dann spricht das Team nur noch über Controller, Repository und Entity, aber nicht mehr über Bestellung, Zahlung, Rechnung, Storno oder Lieferfreigabe. Gute Enterprise-Architektur beginnt mit einem fachlichen Modell und bildet dieses Modell technisch kontrolliert ab.

#Fachliche Sicht

Was passiert im Unternehmen? Welche Entscheidung wird getroffen? Welcher Zustand ändert sich?

#Technische Sicht

Welche Schnittstelle nimmt die Anfrage an? Welche Transaktion läuft? Welche Daten werden gespeichert?

#Betriebliche Sicht

Wie erkennt man Fehler? Wie wird skaliert? Was passiert bei Ausfall von DB, Broker oder Partner-API?

#Typischer Enterprise-Request

Ein einzelner HTTP-Request wirkt einfach, enthält aber viele implizite Entscheidungen: Authentifizierung, Autorisierung, DTO-Mapping, Validierung, Transaktionsstart, Domain-Aufruf, Persistenz, Fehlerbehandlung, Logging, Metriken und Trace-Kontext. Für kleine Demos kann man diese Themen ignorieren. In Enterprise-Systemen müssen sie bewusst standardisiert werden.


#02. Enterprise Java V6

Java-Version, Records, Virtual Threads, Exceptions, Collections und Modularität praxisnah verstehen.

#Java-Version bewusst wählen

In Enterprise-Umgebungen ist die Java-Version eine Architekturentscheidung. Sie betrifft Laufzeit, Security-Patches, Framework-Kompatibilität, Build-Reproduzierbarkeit und Container-Images. Java 21 ist weiterhin eine sehr verbreitete moderne Basis, während Java 25 als aktuelle LTS-Version im Oracle-Ökosystem relevant ist. Für viele Frameworks bleibt Java 17 das Minimum, aber Java 21 ist häufig die sinnvolle produktive Basis.

text
<properties> <!-- Enterprise-Regel: eine Java-Version bewusst festlegen, nicht implizit vom lokalen JDK erben. --> <maven.compiler.release> 21 </maven.compiler.release> <project.build.sourceEncoding> UTF-8 </project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <groupId> org.apache.maven.plugins </groupId> <artifactId> maven-compiler-plugin </artifactId> <version> 3.14.1 </version> </plugin> </plugins> </build>

#Records, Value Objects und DTOs

Records sind ideal für unveränderliche Datencontainer: API-Requests, Responses, Commands, Events und einfache Value Objects. Nicht jede Entity sollte ein Record sein, weil JPA/Hibernate bei Entities besondere Anforderungen an Konstruktoren, Proxies und Lifecycle hat. Für fachliche Wertobjekte und Transportobjekte sind Records jedoch sehr lesbar.

text
public record PlaceOrderCommand ( CustomerId customerId , List < Line > lines ) { public PlaceOrderCommand { Objects . requireNonNull ( customerId , "customerId" ); lines = List . copyOf ( lines ); if ( lines . isEmpty ()) throw new IllegalArgumentException ( "lines must not be empty" ); } public record Line ( String sku , int quantity ) {} }

#Virtual Threads richtig einordnen

Virtual Threads reduzieren den Aufwand blockierender I/O-Operationen, ersetzen aber keine Architekturarbeit. Sie lösen nicht automatisch Datenbank-Locks, schlechte SQLs, fehlende Timeouts oder unkontrollierte Nebenläufigkeit. Sie sind besonders interessant für viele gleichzeitige blockierende Requests, solange Bibliotheken und Frameworks korrekt mitspielen.

#Exception-Strategie

Enterprise-Code braucht eine klare Fehler-Taxonomie. Nicht jede Exception ist gleich: Validierungsfehler, Fachfehler, technische Recoverable-Fehler und technische Non-Recoverable-Fehler müssen unterschiedlich behandelt werden.

text
public sealed interface OrderFailure permits ValidationFailure , BusinessFailure , TechnicalFailure {} public record ValidationFailure ( String field , String message ) implements OrderFailure {} public record BusinessFailure ( String code , String message ) implements OrderFailure {} public record TechnicalFailure ( String system , String message , boolean retryable ) implements OrderFailure {} // Pattern: Result Object - erwartbare Fehler werden explizit modelliert statt als Zufalls-Exception geworfen. public record Result < T > ( T value , OrderFailure failure ) { public static < T > Result < T > ok ( T value ) { return new Result <> ( value , null ); } public static < T > Result < T > fail ( OrderFailure failure ) { return new Result <> ( null , failure ); } public boolean isOk () { return failure == null ; } }

#03. Enterprise Java V6

Reproduzierbare Enterprise-Builds, Parent-POMs, BOMs, Plugins und typische Fehler.

#Maven als Architekturwerkzeug

Maven ist nicht nur ein Build-Tool. In Enterprise-Systemen beschreibt Maven Module, Abhängigkeitsrichtung, Versionierung, Plugin-Standards, Security-Checks, Testphasen, Packaging und Release-Konventionen. Ein schlecht gepflegter POM ist oft ein Symptom für schlechte Architekturgrenzen.

text
<dependencyManagement> <dependencies> <dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-dependencies </artifactId> <version> ${spring-boot.version} </version> <type> pom </type> <scope> import </scope> </dependency> </dependencies> </dependencyManagement>

#Modulgrenzen mit Maven erzwingen

Ein sauberer Enterprise-Schnitt vermeidet, dass der Web-Controller direkt auf JPA-Entities, SQL-Helfer oder externe REST-Clients zugreift. Maven-Module können diese Richtung erzwingen: Domain kennt nichts von Frameworks, Application kennt Ports, Adapter implementieren Ports.

text
order-platform
├── order-domain          # reine Fachlichkeit, keine Frameworks
├── order-application     # Use Cases, Ports, Transaktionsabstraktion
├── order-adapter-jpa     # JPA/Hibernate Implementierung
├── order-adapter-rest    # REST Controller / DTO Mapping
└── order-boot            # Runtime, DI, Konfiguration, Startklasse

#Typische Maven-Probleme


#04. Enterprise Java V6

Standardbasierte Enterprise-Entwicklung mit Container-Diensten verstehen.

#Jakarta EE als Standardplattform

Jakarta EE ist eine standardisierte Plattform für Enterprise-Anwendungen. Sie liefert Spezifikationen für Dependency Injection, REST, Persistence, Transactions, Messaging, Security, Validation, Batch und weitere Bereiche. Wichtig ist die Trennung zwischen Spezifikation und Implementierung: Jakarta EE definiert APIs und Verhalten, konkrete Server oder Frameworks liefern die Runtime.

#CDI und Application Service

CDI hilft, Objektgraphen kontrolliert zusammenzubauen. In Enterprise-Code sollte CDI nicht die Fachlogik ersetzen. Die Fachlogik bleibt in Domain- und Application-Services; CDI verdrahtet die Implementierungen.

text
import jakarta.enterprise.context.ApplicationScoped ; import jakarta.inject.Inject ; import jakarta.transaction.Transactional ; @ApplicationScoped public class InvoiceApplicationService { @Inject InvoiceRepository invoices ; @Inject OrderClient orders ; @Inject DomainEventPublisher events ; // Pattern: Transaction Script an der Use-Case-Grenze - bewusst hier, nicht im Controller. @Transactional public InvoiceId createInvoiceFor ( OrderId orderId ) { OrderSnapshot order = orders . load ( orderId ); Invoice invoice = Invoice . from ( order ); invoices . persist ( invoice ); events . publish ( new InvoiceCreated ( invoice . id (), orderId )); return invoice . id (); } }

#JAX-RS Resource sauber schneiden

text
@Path ( "/invoices" ) @Consumes ( MediaType . APPLICATION_JSON ) @Produces ( MediaType . APPLICATION_JSON ) public class InvoiceResource { @Inject InvoiceApplicationService service ; @POST public Response create ( CreateInvoiceRequest request ) { InvoiceId id = service . createInvoiceFor ( request . orderId ()); return Response . created ( URI . create ( "/invoices/" + id . value ())) . entity ( new CreateInvoiceResponse ( id . value ())) . build (); } }

#Jakarta EE 11 Modernisierung

Jakarta EE 11 ist relevant, weil es moderne Java-Sprachmerkmale besser berücksichtigt und Java 17+ als Basis setzt. Für Legacy-Projekte ist der wichtigste Schritt oft nicht sofort Jakarta EE 11, sondern die kontrollierte Migration von javax.* zu jakarta.* , die Aktualisierung des Application Servers und die Entkopplung alter EJB-/SOAP-/JSP-Schichten.


#05. Enterprise Java V6

Auto-Configuration verstehen, nicht blind benutzen: Controller, Services, Configuration, Profiles, Actuator.

#Spring Boot in Enterprise-Systemen

Spring Boot ist stark, weil es Konventionen, Auto-Configuration, Starter, Actuator, Security-Integration, Testunterstützung und Cloud-Native-Betrieb zusammenbringt. Die Gefahr ist, dass Architekturentscheidungen in zufälligen Annotationen verschwinden. Gute Spring-Systeme halten Fachgrenzen explizit.

#Controller, DTO und Use Case

text
@RestController @RequestMapping ( "/api/orders" ) class OrderController { private final PlaceOrderUseCase placeOrder ; OrderController ( PlaceOrderUseCase placeOrder ) { this . placeOrder = placeOrder ; } @PostMapping ResponseEntity < OrderResponse > create ( @Valid @RequestBody PlaceOrderRequest request ) { OrderId id = placeOrder . handle ( request . toCommand ()); URI location = URI . create ( "/api/orders/" + id . value ()); return ResponseEntity . created ( location ). body ( new OrderResponse ( id . value ())); } }

Der Controller übersetzt HTTP in einen Use Case. Er sollte nicht entscheiden, wie Preise berechnet, Rechnungen erzeugt oder Events publiziert werden. Diese Entscheidungen gehören in Application Service und Domain.

#Spring Configuration als Adapter-Zentrale

text
@Configuration class OrderModuleConfiguration { @Bean PlaceOrderUseCase placeOrderUseCase ( OrderRepository repository , DomainEventPublisher eventPublisher , PricingPolicy pricingPolicy ) { return new PlaceOrderUseCase ( repository , eventPublisher , pricingPolicy ); } @Bean PricingPolicy pricingPolicy ( ProductCatalogClient catalog ) { // Pattern: Adapter + Strategy - Preisstrategie kann pro Kontext ausgetauscht werden. return new CatalogBackedPricingPolicy ( catalog ); } }

#Actuator und Betriebsfähigkeit

Enterprise-Anwendungen müssen betrieblich beobachtbar sein. Readiness bedeutet: Kann diese Instanz Traffic annehmen? Liveness bedeutet: Muss diese Instanz neugestartet werden? Health Checks dürfen nicht zu schwer sein und sollten Abhängigkeiten bewusst modellieren.

text
management : endpoints : web : exposure : include : health,info,metrics,prometheus endpoint : health : probes : enabled : true show-details : when_authorized

#06. Enterprise Java V6

Cloud-native Java, schnelle Starts, Standards, Fault Tolerance, Config, Health und OpenAPI.

#Quarkus richtig verstehen

Quarkus optimiert Java für Container- und Cloud-Native-Szenarien. Es arbeitet stark zur Build-Zeit, unterstützt viele Standards aus Jakarta EE und MicroProfile und ist besonders interessant, wenn Startzeit, Speicherverbrauch, Developer Loop und native Images wichtig sind. Trotzdem bleiben Architekturprinzipien gleich: Fachlogik entkoppeln, Adapter schneiden, Fehlerverträge definieren.

text
@Path ( "/orders" ) @Consumes ( MediaType . APPLICATION_JSON ) @Produces ( MediaType . APPLICATION_JSON ) public class OrderResource { @Inject PlaceOrderUseCase placeOrder ; @POST @Transactional public Response create ( @Valid PlaceOrderRequest request ) { OrderId id = placeOrder . handle ( request . toCommand ()); return Response . created ( URI . create ( "/orders/" + id . value ())). build (); } }

#MicroProfile als Microservice-Standardset

MicroProfile ergänzt Jakarta EE-orientierte APIs um typische Microservice-Themen: Config, REST Client, Fault Tolerance, Health, Metrics/Telemetry, OpenAPI und JWT. Das Ziel ist nicht, jedes Problem mit Annotationen zu lösen, sondern Standardverhalten für wiederkehrende Betriebssituationen bereitzustellen.

text
@ApplicationScoped public class PartnerRatingClient { @Inject @RestClient PartnerApi partnerApi ; @Retry ( maxRetries = 3 , delay = 250 ) @Timeout ( 1000 ) @Fallback ( fallbackMethod = "fallbackRating" ) public PartnerRating loadRating ( String partnerId ) { return partnerApi . rating ( partnerId ); } PartnerRating fallbackRating ( String partnerId ) { return PartnerRating . unknown ( partnerId ); } }

#Native Image einordnen

Native Images können Startzeit und Speicherverbrauch verbessern, bringen aber Build-Komplexität, Reflection-Konfiguration und Debugging-Besonderheiten mit. Sie sind wertvoll für Serverless, elastische Workloads oder sehr dichte Container-Landschaften, aber nicht automatisch die beste Wahl für jedes Enterprise-System.


#07. Enterprise Java V6

Compile-Time DI, schlanke Microservices und testbare modulare Anwendungen.

#Micronaut im Vergleich

Micronaut setzt stark auf Compile-Time Dependency Injection und vermeidet dadurch viel Runtime-Reflection. Das kann für Microservices, Serverless und schnelle Starts interessant sein. Für Teams ist vor allem wichtig, dass die Architektur nicht allein aus Framework-Magie besteht: Controller bleiben Adapter, Use Cases bleiben fachlich, Clients erhalten klare Timeout- und Fehlerregeln.

text
@Controller ( "/orders" ) class OrderController { private final PlaceOrderUseCase placeOrder ; OrderController ( PlaceOrderUseCase placeOrder ) { this . placeOrder = placeOrder ; } @Post HttpResponse < OrderResponse > create ( @Body @Valid PlaceOrderRequest request ) { OrderId id = placeOrder . handle ( request . toCommand ()); return HttpResponse . created ( new OrderResponse ( id . value ())); } }

#Wann Micronaut sinnvoll ist

#Client- und Konfigurationsdisziplin

In jedem Microservice-Framework gilt: Externe Clients brauchen Timeouts, Retry-Strategien, Fehler-Mapping und Observability. Ohne diese Regeln wird ein einzelner Partnerausfall schnell zur Kaskade im ganzen System.


#08. Enterprise Java V6

Entities, Aggregate, Fetching, Locking, Migrationen und Performancefallen.

#Entity ist nicht automatisch Domain

JPA/Hibernate erleichtert Persistenz, kann aber Fachmodell und Datenmodell vermischen. Eine Entity ist ein persistierbares Objekt mit Lifecycle, Identität und Mapping-Regeln. Ein Domain-Aggregat ist ein fachlicher Konsistenzbereich. Beide können identisch sein, müssen es aber nicht.

text
package com.example.order.domain ; import java.math.BigDecimal ; import java.util.ArrayList ; import java.util.List ; import java.util.Objects ; import java.util.UUID ; // Pattern: Aggregate Root - Order schützt die Konsistenz der Positionsliste und Statusübergänge. public class Order { private final OrderId id ; private final CustomerId customerId ; private final List < OrderLine > lines = new ArrayList <> (); private OrderStatus status = OrderStatus . DRAFT ; public Order ( OrderId id , CustomerId customerId ) { this . id = Objects . requireNonNull ( id ); this . customerId = Objects . requireNonNull ( customerId ); } public static Order draftFor ( CustomerId customerId ) { return new Order ( new OrderId ( UUID . randomUUID ()), customerId ); } public void addLine ( String sku , int quantity , BigDecimal unitPrice ) { if ( status != OrderStatus . DRAFT ) { throw new IllegalStateException ( "Only draft orders can be changed" ); } if ( quantity <= 0 || unitPrice . signum () < 0 ) { throw new IllegalArgumentException ( "Quantity and price must be valid" ); } lines . add ( new OrderLine ( sku , quantity , unitPrice )); } public void place () { if ( lines . isEmpty ()) throw new IllegalStateException ( "Order must contain at least one line" ); status = OrderStatus . PLACED ; } public BigDecimal total () { return lines . stream () . map ( OrderLine :: lineTotal ) . reduce ( BigDecimal . ZERO , BigDecimal :: add ); } }

#N+1 und Fetching verstehen

Viele Performanceprobleme entstehen nicht durch „Hibernate ist langsam“, sondern durch unpassende Fetch-Strategien für konkrete Use Cases. Schreibmodelle brauchen Konsistenz. Lesemodelle brauchen oft Projektionen.

text
// Problem: N+1 Queries, wenn jede Order später lazy ihre Lines lädt. List < OrderEntity > orders = entityManager . createQuery ( "select o from OrderEntity o" , OrderEntity . class ) . getResultList (); orders . forEach ( o -> log . info ( "{} lines" , o . getLines (). size ())); // Besser für Lese-Use-Case: gezielte Fetch-Strategie oder Projektion. List < OrderSummary > summaries = entityManager . createQuery ( """ select new com.example.OrderSummary(o.id, c.name, sum(l.quantity * l.unitPrice)) from OrderEntity o join o.customer c join o.lines l group by o.id, c.name """ , OrderSummary . class ) . getResultList ();

#Locking und Konsistenz

#Migrationen

Schema-Migrationen gehören in den Delivery-Prozess. Tools wie Flyway oder Liquibase sind nicht nur technische Helfer, sondern ein Vertrag zwischen Code-Version und Datenbankschema. Jede Migration sollte klein, nachvollziehbar, vorwärtskompatibel und rollback-bewusst sein.

text
-- V30260707_01__create_order_tables.sql create table orders ( id uuid primary key , customer_id uuid not null , status varchar ( 30 ) not null , version bigint not null default 0 , created_at timestamp not null ); create table order_lines ( id uuid primary key , order_id uuid not null references orders ( id ), sku varchar ( 80 ) not null , quantity integer not null check ( quantity > 0 ), unit_price numeric ( 19 , 2 ) not null check ( unit_price >= 0 ) );

#09. Enterprise Java V6

Asynchronität, Events, Commands, DLQ, Idempotenz und Outbox.

#Warum Messaging nicht nur Technik ist

Messaging wird oft eingeführt, um Systeme zu entkoppeln. Ohne fachliche Ereignisse, stabile Verträge und Fehlerstrategie entsteht aber nur verteiltes Chaos. Ein Event beschreibt eine fachlich abgeschlossene Tatsache. Ein Command fordert eine Aktion an. Diese Unterscheidung ist entscheidend für Ownership und Verantwortung.

#JMS und Kafka vergleichen

#Idempotenz und DLQ

text
public class OrderPlacedConsumer { private final KafkaConsumer < String , OrderPlacedEvent > consumer ; private final BillingService billing ; public void pollLoop () { while ( true ) { ConsumerRecords < String , OrderPlacedEvent > records = consumer . poll ( Duration . ofSeconds ( 1 )); for ( ConsumerRecord < String , OrderPlacedEvent > record : records ) { try { billing . createInvoice ( record . value ()); consumer . commitSync ( Map . of ( record . topicPartition (), new OffsetAndMetadata ( record . offset () + 1 ))); } catch ( RecoverableBillingException ex ) { // Pattern: Retry / Dead Letter - nicht endlos denselben Datensatz blockieren. retryOrSendToDlq ( record , ex ); } } } } }

#Outbox Pattern

Das Outbox Pattern löst das klassische Problem: Eine Datenbankänderung und ein Event müssen zuverlässig zusammengehören, aber Datenbank und Broker bilden keine einfache gemeinsame Transaktion. Deshalb schreibt der Use Case zuerst Fachdaten und Outbox-Eintrag in derselben DB-Transaktion. Ein separater Publisher versendet Outbox-Einträge an den Broker.

text
@Transactional public void placeOrder ( PlaceOrderCommand command ) { Order order = orderFactory . create ( command ); order . place (); orderRepository . save ( order ); // Pattern: Transactional Outbox - Event wird in derselben DB-Transaktion festgehalten. outboxRepository . append ( new OutboxMessage ( "OrderPlaced" , order . id (). value (). toString (), json . serialize ( OrderPlaced . from ( order )) )); }

#10. Enterprise Java V6

HTTP-APIs, OpenAPI, WSDL, Bind/Process, Fehlerverträge und Versionierung.

#REST als fachlicher Vertrag

REST ist nicht nur @GetMapping . Ein gutes API beschreibt Ressourcen, Statuscodes, Fehlerformat, Idempotenz, Versionierung, Paging, Filter, Security und Observability. Für Enterprise-Systeme sind Fehlerszenarien genauso wichtig wie Erfolgsszenarien.

#SOAP: Bind und Process trennen

Bei SOAP-Projekten entstehen Fehler oft dadurch, dass XML-Binding, Schema-Validierung und fachliche Verarbeitung vermischt werden. Das Binding wandelt XML in Java-Strukturen und zurück. Der Prozess führt den Use Case aus. Diese Trennung macht Tests, Fehlermapping und Migration viel leichter.

text
@WebService ( targetNamespace = "urn:partner:rating:v1" , name = "PartnerRatingPort" ) public interface PartnerRatingPort { @WebMethod ( operationName = "GetPartnerRating" ) PartnerRatingResponse getPartnerRating ( PartnerRatingRequest request ); } @WebService ( endpointInterface = "com.example.partner.PartnerRatingPort" ) public class PartnerRatingEndpoint implements PartnerRatingPort { private final PartnerRatingService service ; @Override public PartnerRatingResponse getPartnerRating ( PartnerRatingRequest request ) { // Bind: SOAP/XML wurde bereits in Java-DTOs gemappt. // Process: hier beginnt die fachliche Verarbeitung. return PartnerRatingResponse . from ( service . calculate ( request . partnerId ())); } }

#Adapter für Partner-Systeme

text
public interface PartnerRatingGateway { PartnerRating loadRating ( PartnerId partnerId ); } // Pattern: Anti-Corruption Layer - fremde SOAP-Strukturen bleiben außerhalb der Domain. public class SoapPartnerRatingGateway implements PartnerRatingGateway { private final PartnerRatingPort port ; @Override public PartnerRating loadRating ( PartnerId partnerId ) { PartnerRatingRequest request = PartnerRatingRequestMapper . toSoap ( partnerId ); PartnerRatingResponse response = port . getPartnerRating ( request ); return PartnerRatingMapper . toDomain ( response ); } }

#11. Enterprise Java V6

Sicherheit als Architekturquerschnitt statt späteres Add-on.

#Security-Grundmodell

Enterprise Security besteht aus mehreren Schichten: Transport-Sicherheit, Authentifizierung, Autorisierung, Eingabevalidierung, Secret Management, Audit, sichere Defaults und Dependency-Sicherheit. Ein Framework kann vieles bereitstellen, aber die fachlichen Rechte und Datenzugriffe muss das Team modellieren.

#Spring Security Resource Server

text
@Bean SecurityFilterChain apiSecurity ( HttpSecurity http ) throws Exception { return http . authorizeHttpRequests ( auth -> auth . requestMatchers ( HttpMethod . GET , "/actuator/health" ). permitAll () . requestMatchers ( "/api/admin/**" ). hasAuthority ( "SCOPE_admin" ) . requestMatchers ( "/api/orders/**" ). hasAuthority ( "SCOPE_orders" ) . anyRequest (). authenticated ()) . oauth2ResourceServer ( oauth2 -> oauth2 . jwt ( Customizer . withDefaults ())) . csrf ( csrf -> csrf . disable ()) . build (); }

#Security im Code nicht verstreuen

text
public class CustomerAccessPolicy { // Pattern: Policy Object - fachliche Zugriffsregel ist testbar und nicht in Controller verstreut. public boolean canReadCustomer ( UserPrincipal user , CustomerId customerId ) { return user . hasScope ( "customers:read" ) && ( user . isEmployee () || user . customerIds (). contains ( customerId )); } }

#12. Enterprise Java V6

Logs, Metriken, Traces, Health, SLOs und Fehleranalyse im Enterprise-Betrieb.

#Drei Signale plus Kontext

Observability bedeutet, das System aus seinen Signalen verstehen zu können: Logs erklären Ereignisse, Metriken zeigen Trends und SLO-Verletzungen, Traces zeigen verteilte Aufrufketten. Ohne Korrelation über Request-ID, Trace-ID und fachliche IDs bleibt Fehleranalyse langsam.

text
public class OrderTracingService { private final Tracer tracer ; public void placeOrder ( PlaceOrderCommand command ) { Span span = tracer . spanBuilder ( "order.place" ) . setAttribute ( "customer.id" , command . customerId (). value (). toString ()) . startSpan (); try ( Scope ignored = span . makeCurrent ()) { // Fachlogik bleibt gleich; Trace-Kontext wandert über HTTP/Kafka weiter. handle ( command ); } catch ( Exception ex ) { span . recordException ( ex ); span . setStatus ( StatusCode . ERROR ); throw ex ; } finally { span . end (); } } }

#Health Checks richtig bauen

Readiness und Liveness müssen unterschiedliche Fragen beantworten. Eine DB-Störung kann Readiness beeinflussen, aber ein Service muss nicht sofort gekillt werden. Ein schlechter Liveness-Check kann bei externer Störung eine Neustart-Schleife erzeugen.

#SLO-orientierte Diagnose

Enterprise-Betrieb braucht Ziele: Verfügbarkeit, Latenz, Fehlerrate und Datenqualität. Metriken sind nicht nur Dashboards, sondern Entscheidungsgrundlage für Architektur: Caching, Partitionierung, Backpressure, Skalierung und Priorisierung.


#13. Enterprise Java V6

Unit, Integration, Contract, Mutation, Architecture Tests und Testdatenstrategie.

#Testpyramide für Enterprise Java

Enterprise-Tests sollen schnelles Feedback und reale Sicherheit kombinieren. Unit-Tests prüfen Domain-Regeln. Integrationstests prüfen DB, Broker und Framework-Konfiguration. Contract-Tests schützen Schnittstellen. End-to-End-Tests prüfen wenige kritische Gesamtabläufe.

text
@Testcontainers class OrderRepositoryIT { @Container static PostgreSQLContainer <?> postgres = new PostgreSQLContainer <> ( "postgres:16-alpine" ); @Test void persistsOrderWithLines () { OrderRepository repository = repositoryFor ( postgres . getJdbcUrl ()); Order order = Order . draftFor ( new CustomerId ( UUID . randomUUID ())); order . addLine ( "SKU-1" , 2 , new BigDecimal ( "19.90" )); order . place (); repository . save ( order ); assertThat ( repository . findById ( order . id ())). isPresent (); } }

#Architekturtests

text
@AnalyzeClasses ( packages = "com.example.order" ) class ArchitectureRulesTest { @ArchTest static final ArchRule domain_is_framework_free = noClasses () . that (). resideInAPackage ( "..domain.." ) . should (). dependOnClassesThat (). resideInAnyPackage ( "org.springframework.." , "jakarta.persistence.." , "jakarta.ws.rs.." ); @ArchTest static final ArchRule adapters_do_not_call_each_other = noClasses () . that (). resideInAPackage ( "..adapter.." ) . should (). dependOnClassesThat (). resideInAPackage ( "..adapter.." ); }

#14. Enterprise Java V6

Vom JAR zum betriebenen Service: Images, Ressourcen, Probes, Config, Secrets und Rollouts.

#Container ist kein Deployment-Konzept allein

Ein Dockerfile macht noch kein betreibbares System. Enterprise Deployment braucht Versionierung, Konfiguration, Secrets, Ressourcen, Probes, Rollout-Strategien, Migrationsplan, Monitoring und Incident-Fähigkeit.

text
FROM eclipse-temurin:21-jre WORKDIR /app COPY target/order-service.jar app.jar EXPOSE 8080 ENTRYPOINT [ "java" , "-XX:MaxRAMPercentage=75" , "-jar" , "app.jar" ]
text
apiVersion : apps/v1 kind : Deployment metadata : name : order-service spec : replicas : 3 selector : matchLabels : { app : order-service } template : metadata : labels : { app : order-service } spec : containers : - name : app image : registry.example.com/order-service:1.0.0 ports : [{ containerPort : 8080 }] readinessProbe : httpGet : { path : /actuator/health/readiness , port : 8080 } livenessProbe : httpGet : { path : /actuator/health/liveness , port : 8080 } resources : requests : { cpu : "250m" , memory : "512Mi" } limits : { cpu : "1" , memory : "1024Mi" }

#Konfiguration und Secrets

#Rollout und Rückwärtskompatibilität

Rolling Updates bedeuten, dass alte und neue Versionen kurzzeitig gleichzeitig laufen. APIs, Events und Datenbankschema müssen dafür kompatibel sein. Eine Datenbankspalte entfernen ist fast nie ein einzelner Schritt; zuerst hinzufügen, doppelt schreiben/lesen, migrieren, dann später entfernen.


#15. Enterprise Java V6

Pattern nicht als Theorie, sondern mit Zweck, Einsatzort und Warnsignal.

#Wichtige Muster im Beispielprojekt

#Monster-Methode refactoren

Viele Legacy-Systeme enthalten Methoden, die Validierung, Mapping, DB-Zugriff, SOAP-Aufruf, Statusänderung, Logging und Fehlerbehandlung mischen. Refactoring beginnt nicht mit „alles neu“, sondern mit sichtbaren Schnitten.

text
public InvoiceId createInvoice ( CreateInvoiceRequest request ) { validate ( request ); OrderSnapshot order = orderGateway . load ( request . orderId ()); Invoice invoice = invoiceFactory . from ( order ); invoiceRepository . save ( invoice ); outbox . append ( InvoiceCreated . from ( invoice )); return invoice . id (); }

#Entscheidungsregeln


#16. Enterprise Java V6

Verstehen, absichern, strangeln, extrahieren und modernisieren ohne Blindflug.

#Modernisierung beginnt mit Verstehen

Legacy-Code ist nicht automatisch schlecht. Er enthält Geschäftsregeln, Ausnahmen, historische Partnerverträge und Produktionswissen. Modernisierung bedeutet, dieses Wissen zu sichern, bevor Technik ersetzt wird.

#Strangler Fig praktisch

text
public class OrderFacade { private final LegacyOrderService legacy ; private final ModernOrderService modern ; private final MigrationSwitch migrationSwitch ; // Pattern: Facade + Strangler Fig - Aufrufer bleiben stabil, Implementierung wandert schrittweise. public OrderResponse placeOrder ( PlaceOrderRequest request ) { if ( migrationSwitch . useModernPath ( request . customerSegment ())) { return modern . placeOrder ( request ); } return legacy . placeOrder ( request ); } }

#javax zu jakarta

Die Umstellung von javax.* auf jakarta.* ist nicht nur Suchen/Ersetzen. Application Server, Libraries, Annotation Processor, SOAP/JAX-WS, JPA Provider, Validation, Security und Tests müssen zusammenpassen. Besonders kritisch sind alte Bibliotheken, die noch javax -APIs erwarten.


#17. Enterprise Java V6

Von Java 8/11/17 zu Java 21/25: Sprache, Build, Runtime, Libraries, Container und Tests sicher modernisieren.

#Warum eine Java-Migration kein reines JDK-Update ist

Eine Enterprise-Java-Migration betrifft Quellcode, Bytecode, Build-Plugins, Container-Images, Reflection, Security Provider, TLS, JDBC-Treiber, Application Server, Libraries und Betriebsprozesse. Java 21 ist für viele Unternehmen die moderne produktive Basis; Java 25 ist die aktuelle LTS-Linie und sollte für neue Zielplattformen geprüft werden. Wichtig ist eine kontrollierte Sequenz statt Big Bang.

#Empfohlene Reihenfolge

Zuerst wird der Build reproduzierbar gemacht: Maven Compiler Plugin, Toolchains, Enforcer und CI-Image. Danach werden Tests und Characterization Tests ergänzt. Anschließend kommen Library-Upgrades, javax/jakarta-Analyse, Container-Images, Performancevergleich und produktionsnahe Lasttests.

#Typische Modernisierungsgewinne

Records reduzieren DTO-Boilerplate, sealed types machen Fehler- und Statusmodelle klarer, Pattern Matching vereinfacht Routinglogik und Virtual Threads können blockierende I/O-Workloads vereinfachen. Der Gewinn entsteht aber erst, wenn Code und Architektur darauf vorbereitet sind.

#Entscheidungen

#Ausführliche Beispiele

text
<properties> <maven.compiler.release> 21 </maven.compiler.release> </properties> <build> <plugins> <plugin> <groupId> org.apache.maven.plugins </groupId> <artifactId> maven-toolchains-plugin </artifactId> <version> 3.2.0 </version> <executions> <execution> <goals><goal> toolchain </goal></goals> </execution> </executions> <configuration> <toolchains> <jdk> <version> 21 </version> <vendor> any </vendor> </jdk> </toolchains> </configuration> </plugin> </plugins> </build>
text
public sealed interface MigrationRisk permits BuildRisk , RuntimeRisk , LibraryRisk {} public record BuildRisk ( String plugin , String reason ) implements MigrationRisk {} public record RuntimeRisk ( String component , String reason ) implements MigrationRisk {} public record LibraryRisk ( String dependency , String reason ) implements MigrationRisk {} public static String owner ( MigrationRisk risk ) { return switch ( risk ) { case BuildRisk ignored -> "Build/CI Team" ; case RuntimeRisk ignored -> "Platform Team" ; case LibraryRisk ignored -> "Application Team" ; }; }

#Typische Stolperfallen


#18. Enterprise Java V6

Heap, GC, JFR, Thread Dumps, Connection Pools, Virtual Threads und messbare Performance-Hypothesen.

#Performance beginnt vor dem Tuning

Viele Performanceprobleme entstehen durch fachliche oder architektonische Entscheidungen: zu große Aggregate, N+1 Queries, zu lange Transaktionen, fehlende Pagination, ungünstige Batchgrößen oder Remote Calls in kritischen Pfaden. JVM-Flags sind selten die erste Lösung.

#Diagnosewerkzeuge

GC-Logs zeigen Speicher- und Pausenverhalten. JFR zeigt Locks, Methoden, Allocation, I/O und Threads. Thread Dumps helfen bei Deadlocks und blockierenden Aufrufen. Metriken zeigen Trends, Traces zeigen verteilte Latenz.

#Virtual Threads im Betrieb

Virtual Threads können blockierende I/O-Szenarien vereinfachen, aber Datenbank- und HTTP-Pools bleiben Ressourcen. Wenn 10.000 virtuelle Threads auf 30 DB-Verbindungen warten, ist die Datenbank weiterhin die Grenze.

#Entscheidungen

#Ausführliche Beispiele

text
java \ -XX:StartFlightRecording = filename = /var/log/order/startup.jfr,dumponexit = true \ -Xlog:gc*:file = /var/log/order/gc.log:time,uptime,level,tags \ -XX:MaxRAMPercentage = 75 \ -jar order-service.jar
text
// Anti-Pattern: alle Datensätze laden und im Speicher filtern. List < Order > all = orderRepository . findAll (); return all . stream (). filter ( Order :: isOpen ). toList (); // Besser: fachliche Query mit Limit und Sortierung. return orderRepository . findOpenOrders ( PageRequest . of ( 0 , 100 ));

#Typische Stolperfallen


#19. Enterprise Java V6

Repository-Methoden, Projections, Specifications, JdbcClient, CQRS-light und saubere Query-Grenzen.

#Repository ist keine Abkürzung um Use Cases herum

Spring Data spart Code, aber Controller sollten nicht direkt Repositories orchestrieren. Der Use Case definiert, welche Daten fachlich gebraucht werden, und das Repository liefert eine passende Abfrage.

#Read Model statt Entity-Leak

Listenansichten, Suchseiten und Reports brauchen selten komplette Aggregates. Projections oder eigene Read Models reduzieren Datenvolumen und verhindern Lazy-Loading-Fallen.

#JPA und JDBC kombinieren

JPA eignet sich für Aggregate und transaktionale Änderungen. JDBC oder SQL-Projections sind oft klarer für komplexe Reports, Massenabfragen und optimierte Read-Modelle.

#Entscheidungen

#Ausführliche Beispiele

text
public interface OrderListProjection { UUID getId (); String getCustomerNumber (); BigDecimal getTotalAmount (); Instant getCreatedAt (); } interface OrderJpaRepository extends JpaRepository < OrderEntity , UUID > { List < OrderListProjection > findByStatusOrderByCreatedAtDesc ( OrderStatus status ); }
text
public List < OrderListView > findOpenOrdersForDashboard () { return jdbcClient . sql ( """ select o.id, c.customer_number, o.total_amount, o.created_at from orders o join customers c on c.id = o.customer_id where o.status = :status order by o.created_at desc limit 100 """ ) . param ( "status" , "OPEN" ) . query ( OrderListView . class ) . list (); }

#Typische Stolperfallen


#20. Enterprise Java V6

Config, REST Client, Fault Tolerance, JWT, Health, OpenAPI und Telemetry als Standard-Bausteine.

#MicroProfile als Enterprise-Standardisierung

MicroProfile reduziert Wildwuchs bei Microservices. Statt jedes Team eigene Health Checks, REST Clients, Retries und API-Dokumentation baut, liefern Spezifikationen ein gemeinsames Programmiermodell.

#Fault Tolerance richtig einsetzen

Timeout kommt vor Retry. Retry braucht Idempotenz. Circuit Breaker braucht Metriken. Bulkheads verhindern, dass ein langsames System alle Ressourcen blockiert.

#Health ist kein Monitoring-Ersatz

Health Checks steuern Plattformverhalten. Monitoring erklärt Trends, Fehler und Latenzen. Liveness, Readiness und Startup sollten getrennt werden.

#Entscheidungen

#Ausführliche Beispiele

text
@RegisterRestClient ( configKey = "customer-api" ) public interface CustomerClient { @GET @Path ( "/customers/{id}" ) @Timeout ( 1000 ) @Retry ( maxRetries = 2 , delay = 100 ) CustomerDto find ( @PathParam ( "id" ) String id ); }
text
@Readiness @ApplicationScoped public class DatabaseReadiness implements HealthCheck { public HealthCheckResponse call () { boolean ok = database . ping ( Duration . ofSeconds ( 1 )); return HealthCheckResponse . named ( "database" ). status ( ok ). build (); } }

#Typische Stolperfallen


#21. Enterprise Java V6

Compile-Time DI, AOT, HTTP Clients, Configuration, Tests und Framework-Entscheidung.

#Compile-Time statt Laufzeit-Magie

Micronaut erzeugt viel Metadatenarbeit zur Compile-Zeit. Das reduziert Reflection und kann schnelle Starts sowie geringeren Speicherbedarf unterstützen.

#Wann Micronaut passt

Micronaut ist interessant für Microservices, Serverless, modulare Services und Teams, die Compile-Time DI bewusst nutzen wollen. Entscheidend bleibt die Unternehmensreife: Wissen, Support, Libraries und Betrieb.

#Framework-Migration realistisch bewerten

Ein Wechsel von Spring oder Jakarta EE zu Micronaut ist nicht nur Annotationstausch. Konfiguration, Testing, Security, Datenzugriff, Observability und Build-Prozess müssen zusammen betrachtet werden.

#Entscheidungen

#Ausführliche Beispiele

text
@Controller ( "/orders" ) public class OrderController { private final PlaceOrderUseCase placeOrder ; public OrderController ( PlaceOrderUseCase placeOrder ) { this . placeOrder = placeOrder ; } @Post HttpResponse < IdResponse > place ( @Body PlaceOrderRequest request ) { OrderId id = placeOrder . place ( request . toCommand ()); return HttpResponse . created ( new IdResponse ( id . value ())); } }
text
@ConfigurationProperties ( "partner.billing" ) public record BillingConfiguration ( URI baseUrl , Duration timeout , int maxRetries ) {}

#Typische Stolperfallen


#22. Enterprise Java V6

Ressourcen, DTOs, Statuscodes, Problem Details, Versionierung, Pagination und Idempotency-Key.

#REST ist ein Vertrag

REST APIs sind langlebige Verträge. Sie brauchen klare Ressourcen, Statuscodes, Fehlerformat, Security, Versionierung und Beispiele. Controller-Code ist nur die technische Oberfläche dieses Vertrags.

#Problem Details im Enterprise-Kontext

Clients müssen unterscheiden können: Eingabe ungültig, Objekt nicht gefunden, fachlicher Konflikt, technische Störung, temporärer Fehler. Ein einheitliches Fehlerformat senkt Integrationsaufwand.

#Idempotenz für kritische Kommandos

Bei Bestellung, Zahlung, Storno oder Buchung muss ein Retry ungefährlich sein. Ein Idempotency-Key verhindert doppelte Effekte.

#Entscheidungen

#Ausführliche Beispiele

text
{ "type" : "https://errors.example.com/order/credit-limit-exceeded" , "title" : "Credit limit exceeded" , "status" : 409 , "detail" : "Customer C-4711 cannot place an order above 5000 EUR." , "traceId" : "4f7b9c0e6d2a" , "violations" : [] }
text
public IdResponse place ( String idempotencyKey , PlaceOrderRequest request ) { return idempotencyStore . executeOnce ( idempotencyKey , () -> { OrderId id = placeOrder . place ( request . toCommand ()); return new IdResponse ( id . value ()); }); }

#Typische Stolperfallen


#23. Enterprise Java V6

WSDL, XSD, Binding, Process, SOAP Faults und Fassade vor Altsystemen.

#Warum SOAP wichtig bleibt

In Banken, Versicherungen, Behörden und B2B-Landschaften ist SOAP oft weiterhin produktiv. Verträge, XSD-Typen und WS-* Erweiterungen sind in solchen Umgebungen kein Zufall, sondern Stabilitätsfaktor.

#Contract-first statt Java-first

Der Vertrag soll bewusst versioniert und fachlich geprüft werden. Java-Code wird gegen WSDL/XSD gebaut, nicht zufällig zum öffentlichen Vertrag.

#Portal kommuniziert über Fassade

Ein Portal sollte Altsystemdetails nicht direkt kennen. Eine Fassade übersetzt Fehler, Datenformate und Sicherheitskontext.

#Entscheidungen

#Ausführliche Beispiele

text
<xs:complexType name= "PlaceOrderRequest" > <xs:sequence> <xs:element name= "customerNumber" type= "xs:string" /> <xs:element name= "orderLine" type= "tns:OrderLine" minOccurs= "1" maxOccurs= "unbounded" /> </xs:sequence> </xs:complexType>
text
public final class SoapBillingAdapter implements BillingPort { private final BillingSoapClient client ; // Pattern: Adapter - SOAP-Vertrag bleibt außerhalb des Use Case. public InvoiceId createInvoice ( Order order ) { CreateInvoiceResponse response = client . createInvoice ( SoapMapper . toRequest ( order )); return new InvoiceId ( response . getInvoiceNumber ()); } }

#Typische Stolperfallen


#24. Enterprise Java V6

Domain Events, Kafka, JMS, Outbox, Schema Evolution, Ordering, Replay und DLQ.

#Event ist eine fachliche Tatsache

Ein Event beschreibt, was passiert ist: OrderPlaced, PaymentReserved, InvoiceCreated. Es ist kein technischer Dump einer Datenbankzeile.

#Outbox als Zuverlässigkeitsmuster

Datenänderung und Event-Erfassung werden in derselben Datenbanktransaktion gespeichert. Ein Publisher publiziert später zuverlässig an Broker oder Streaming-Plattform.

#Consumer sind eigenständige Systeme

Consumer brauchen Idempotenz, Schema-Toleranz, Monitoring, Retry-Strategie und Dead Letter Queue. Ein Event macht Integration nicht automatisch einfach.

#Entscheidungen

#Ausführliche Beispiele

text
public record OrderPlacedEvent ( UUID eventId , UUID orderId , String customerNumber , BigDecimal totalAmount , Instant occurredAt , int schemaVersion ) {}
text
public void onOrderPlaced ( OrderPlacedEvent event ) { if ( processedEvents . exists ( event . eventId ())) { return ; } billingService . createInvoice ( event . orderId ()); processedEvents . markProcessed ( event . eventId ()); }

#Typische Stolperfallen


#25. Enterprise Java V6

Identity Provider, Claims, Rollen, Objektberechtigung, Service-to-Service, Secrets und Audit.

#Security beginnt bei Identität

Authentifizierung klärt, wer aufruft. Autorisierung klärt, was dieser Aufrufer im konkreten Kontext darf. Enterprise-Systeme brauchen häufig Objekt-, Mandanten- und Prozessberechtigungen.

#JWT ist kein Sicherheitszauber

Token müssen auf Signatur, Ablaufzeit, Audience, Issuer und Scopes geprüft werden. Claims sollten stabil, minimal und fachlich sinnvoll sein.

#Service-to-Service getrennt betrachten

Maschinenidentität ist nicht Nutzeridentität. Interne Kommunikation braucht Client Credentials, mTLS, Netzwerkregeln oder Plattformmechanismen.

#Entscheidungen

#Ausführliche Beispiele

text
@PreAuthorize ( "hasAuthority('ORDER_APPROVE') and @orderSecurity.canAccess(#id)" ) public void approve ( OrderId id ) { approveOrderUseCase . approve ( id ); }
text
public CurrentUser currentUser ( Jwt jwt ) { return new CurrentUser ( jwt . getSubject (), jwt . getClaimAsStringList ( "groups" ), jwt . getAudience () ); }

#Typische Stolperfallen


#26. Enterprise Java V6

Logs, Metrics, Traces, Baggage, Sampling, SLOs, Dashboards und fachliche Nachvollziehbarkeit.

#Drei Signale verbinden

Logs erklären Details, Metriken zeigen Verhalten über Zeit, Traces verbinden Aufrufe über Systemgrenzen. Gute Observability macht fachliche Vorgänge sichtbar.

#Trace-Kontext durchreichen

TraceId und fachliche IDs wie orderId oder customerId müssen über HTTP, Messaging und Batch hinweg nachvollziehbar bleiben. Dabei dürfen sensible Daten nicht unkontrolliert in Logs landen.

#SLO statt Dashboard-Sammlung

Dashboards sind nur hilfreich, wenn klar ist, welche Service-Level-Ziele gelten: Latenz, Fehlerrate, Verfügbarkeit, Queue Lag, Durchsatz.

#Entscheidungen

#Ausführliche Beispiele

text
Span span = Span . current (); span . setAttribute ( "business.operation" , "place-order" ); span . setAttribute ( "order.id" , order . id (). value (). toString ()); span . setAttribute ( "customer.id" , order . customerId (). value ());
text
log . info ( "order_placed order={} customer={} total={} traceId={}" , order . id (). value (), order . customerId (). value (), order . total (), MDC . get ( "traceId" ));

#Typische Stolperfallen


#27. Enterprise Java V6

Fehler in verteilten Enterprise-Systemen begrenzen: Bulkhead, Backpressure, Fallback und Idempotenz.

#Teilfehler sind normal

Remote APIs, Broker und Datenbanken können langsam, partiell gestört oder nur für bestimmte Operationen fehlerhaft sein. Resilience verhindert, dass ein Fehler das ganze System mitreißt.

#Timeout vor Retry

Jeder Retry braucht ein Zeitbudget und Idempotenz. Ohne Timeout verstärkt Retry die Last. Ohne Idempotenz erzeugt Retry doppelte Geschäftsvorfälle.

#Fallback darf nicht lügen

Ein Fallback kann degradieren, aber er darf keinen fachlichen Erfolg vortäuschen. Wenn Zahlung unklar ist, sollte die Bestellung auf WAITING_FOR_PAYMENT stehen, nicht APPROVED.

#Entscheidungen

#Ausführliche Beispiele

text
resilience4j : timelimiter : instances : payment : timeout-duration : 2s retry : instances : payment : max-attempts : 2 wait-duration : 100ms circuitbreaker : instances : payment : failure-rate-threshold : 50 sliding-window-size : 20
text
public PaymentDecision reservePayment ( Order order ) { try { return paymentClient . reserve ( order . paymentRequest ()); } catch ( TimeoutException ex ) { return PaymentDecision . pending ( "PAYMENT_TIMEOUT" ); } }

#Typische Stolperfallen


#28. Enterprise Java V6

Spring Batch, Jakarta Batch, CronJobs, Chunking, Restartability, Skip/Retry und fachliche Nachweise.

#Batch ist produktionskritisch

Rechnungsläufe, Exporte, Importe, Mahnungen, Datenabgleiche und Reports laufen oft als Batch. Fehler dort sind nicht kleiner als Fehler in APIs.

#Restartability planen

Ein Batch muss nach Fehler weiterlaufen können. Dafür braucht er Fortschrittsstatus, eindeutige Schlüssel, Checkpoints, Fehlerlisten und klare Wiederanlaufregeln.

#Scheduler ist nur Auslöser

Die fachliche Logik gehört in Use Cases. Dann kann derselbe Prozess per Cron, manuell, Event oder API gestartet werden.

#Entscheidungen

#Ausführliche Beispiele

text
@Bean Step invoiceExportStep ( JobRepository jobs , PlatformTransactionManager tx ) { return new StepBuilder ( "invoiceExport" , jobs ) . < Invoice , ExportLine > chunk ( 500 , tx ) . reader ( invoiceReader ()) . processor ( invoiceProcessor ()) . writer ( exportWriter ()) . faultTolerant () . skip ( InvalidInvoiceException . class ) . skipLimit ( 100 ) . build (); }
text
public record BatchItemKey ( String jobName , String businessKey , LocalDate businessDate ) {}

#Typische Stolperfallen


#29. Enterprise Java V6

Caffeine, Redis, JCache, TTL, Invalidierung, Externalized Config, Secrets und Toggles.

#Caching ist fachliche Entscheidung

Cache verbessert Latenz und reduziert Last, aber erzeugt Stale Data. Deshalb müssen Aktualität, TTL, Invalidierung und Berechtigungen fachlich geklärt werden.

#Konfiguration vom Build trennen

Ein Artefakt soll in mehreren Umgebungen laufen. URLs, Limits, Feature Flags und Secrets gehören in Runtime-Konfiguration, nicht in den Build.

#Feature Flags mit Governance

Flags brauchen Owner, Ziel, Ablaufdatum und Entfernung. Sonst entsteht ein verstecktes zweites Architekturmodell im Code.

#Entscheidungen

#Ausführliche Beispiele

text
public record PriceCacheKey ( String tenantId , String sku , String currency ) {} @Cacheable ( cacheNames = "prices" , key = "#tenantId + ':' + #sku + ':' + #currency" ) public Money price ( String tenantId , String sku , String currency ) { return priceClient . load ( tenantId , sku , currency ); }
text
public boolean shouldUseNewRiskCheck ( Customer customer ) { return flags . enabled ( "new-risk-check" ) && customer . region (). equals ( Region . EU ) && customer . createdAt (). isAfter ( Instant . parse ( "2025-01-01T00:00:00Z" )); }

#Typische Stolperfallen


#30. Enterprise Java V6

ArchUnit, Enforcer, Dependency Checks, Contract Tests, Testcontainers, Coverage und Build-Pipeline.

#Quality Gates schützen Architektur

Gute Regeln werden automatisiert. Sonst gewinnen Zeitdruck und Copy-Paste. Architekturtests prüfen Modulgrenzen, Dependency-Regeln, verbotene Frameworks in der Domain und Namenskonventionen.

#CI/CD als Lernsignal

Eine Pipeline soll schnell Feedback geben: Kompilierung, Unit Tests, Architekturtests, Integrationstests, Security Checks, Packaging und Deployment. Fehler müssen verständlich sein.

#Nicht alles in einen Test werfen

Schnelle Tests laufen früh, teure Tests später. Contract Tests schützen Schnittstellen, Integrationstests prüfen Adapter, End-to-End Tests bleiben sparsam.

#Entscheidungen

#Ausführliche Beispiele

text
@Test void domain_must_not_depend_on_frameworks () { noClasses (). that (). resideInAPackage ( "..domain.." ) . should (). dependOnClassesThat (). resideInAnyPackage ( "org.springframework.." , "jakarta.persistence.." , "jakarta.ws.rs.." ) . check ( importedClasses ); }
text
stages : - compile - unit-test - architecture-test - integration-test - dependency-scan - package - deploy-dev

#Typische Stolperfallen


#31. Enterprise Java V6

Spring Boot, Jakarta EE, Quarkus, Micronaut, Hibernate, Kafka, Maven und OpenTelemetry fachlich vergleichen.

#Keine pauschal beste Technologie

Framework-Auswahl hängt von Teamwissen, Betriebsplattform, Support, Performance, Standardisierung, Migration, Ökosystem und Lebensdauer ab. Eine Technologie kann fachlich falsch sein, obwohl sie technisch modern wirkt.

#Bewertung mit Gewichtung

Kriterien sollten gewichtet werden: Teamkompetenz, Plattformstandard, Startzeit, Speicherbedarf, Standard-APIs, Observability, Security, Migration, Lizenz, Support und Recruiting.

#Mehrere Stacks brauchen Governance

Wenn ein Unternehmen mehrere Frameworks nutzt, braucht es gemeinsame Mindeststandards für Security, Logging, Tracing, CI/CD, API-Fehler, Dependency Management und Betrieb.

#Entscheidungen

#Ausführliche Beispiele

text
criteria : team_experience : 5 platform_fit : 5 startup_time : 3 memory_usage : 3 standard_apis : 4 ecosystem : 5 migration_effort : 5 candidates : spring_boot : { score : 31 , note : "breites Ökosystem" } jakarta_ee : { score : 28 , note : "Standard und App-Server" } quarkus : { score : 29 , note : "Cloud-native und Build-Time" } micronaut : { score : 26 , note : "Compile-time DI" }

#Typische Stolperfallen

#Matrix


#32. Enterprise Java V6

Enterprise-Annotationen nach Kategorie: REST, DI, Transaktionen, JPA, Validation, Security, Resilience und Tests.

#Annotationen sind Laufzeitverträge

Annotationen steuern Routing, Transaktionen, Scopes, Persistenz, Validierung, Security, Resilience und Tests. Sie sind kein Dekor, sondern Architekturverhalten.

#Parameter verstehen

Viele Fehler entstehen durch Defaults: FetchType, Cascade, Propagation, Rollback-Regeln, consumes/produces, Retry-Anzahl, Timeout und Security-Ausdruck.

#Kategorie statt Auswendiglernen

Wer Annotationen nach Verantwortungsbereich lernt, versteht schneller, warum und wo sie eingesetzt werden.

#Entscheidungen

#Ausführliche Beispiele

text
@RestController @RequestMapping ( path = "/api/orders" , produces = MediaType . APPLICATION_JSON_VALUE ) @Validated public class OrderController { @PostMapping ( consumes = MediaType . APPLICATION_JSON_VALUE ) @ResponseStatus ( HttpStatus . CREATED ) public IdResponse place ( @Valid @RequestBody PlaceOrderRequest request ) { return service . place ( request ); } }
text
@Entity @Table ( name = "orders" ) public class OrderEntity { @Id private UUID id ; @Version // Optimistic Locking gegen verlorene Updates private long version ; @OneToMany ( cascade = CascadeType . ALL , orphanRemoval = true , fetch = FetchType . LAZY ) private List < OrderLineEntity > lines = new ArrayList <> (); }

#Typische Stolperfallen

#Annotationenkatalog


#33. Enterprise Java V6

Fachliche und technische Begriffe plus wichtige Entwurfsmuster für Enterprise Java.

#Glossar als Teamvertrag

Ein Glossar verbindet Fachbereich, Entwicklung, Test, Betrieb und Architektur. Es verhindert, dass derselbe Begriff in mehreren Teams unterschiedlich gemeint ist.

#Pattern sind Werkzeuge, keine Dekoration

Entwurfsmuster sind hilfreich, wenn sie ein echtes Problem lösen: Abhängigkeiten kapseln, Erzeugung kontrollieren, Varianten austauschen, Integration robust machen oder Legacy-Sprache isolieren.

#Dokumentation im Projekt

Verwendete Muster sollten im Code kurz markiert und zusätzlich in docs/design-patterns.md dokumentiert werden. Das hilft besonders bei Maven-/Java-Projekten und späterer Wartung.

#Entscheidungen

#Ausführliche Beispiele

text
| Pattern | Zweck | Einsatzort | Begründung |
|---|---|---|---|
| Adapter | Externes System kapseln | HttpPaymentAdapter | Use Case kennt kein HTTP |
| Repository | Persistenz verstecken | OrderRepository | Domain bleibt DB-unabhängig |
| Outbox | Events zuverlässig publizieren | OutboxPublisher | Kein verlorenes Event |
| Saga | Verteilten Prozess steuern | OrderSaga | Kompensation statt 2PC |

#Typische Stolperfallen

#Glossar

#Entwurfsmuster


#34. Enterprise Java V6

Ein durchgehendes Enterprise-Beispielsystem, das die Theorie der vorherigen Kapitel in einen praxisnahen Architektur- und Codezusammenhang bringt.

#Zielbild

Das Praxisprojekt zeigt eine realistische Enterprise-Landschaft: Ein Kundenportal erzeugt Bestellungen, die Order-Domain prüft Invarianten, Inventory reserviert Bestand, Billing erzeugt Rechnungen und ein Event Backbone verteilt fachliche Ereignisse. Wichtig ist nicht, möglichst viele Technologien zu verwenden, sondern die Grenzen sauber sichtbar zu machen.

#Fachlicher Schnitt

#Module

#shared-kernel

Gemeinsame primitive Fachtypen, Result-Typ und DomainEvent.

#order-domain

Aggregate, Value Objects, Policies und Events ohne Framework-Abhängigkeit.

#order-application

Use Cases und Ports. Hier entsteht der fachliche Prozess.

#order-adapters

Repository, Outbox, Legacy-Adapter, Billing-Adapter.

#spring-boot-app

HTTP- und Betriebsschicht für Spring Boot.

#quarkus-app

Cloud-native Variante für Quarkus/MicroProfile.

#docs

ADRs, Pattern-Dokumentation, Teststrategie, Runbooks.

#Bestellablauf

#Code-Slice

text
public final class PlaceOrderUseCase { private final OrderRepository orders ; // Pattern: Repository Port private final InventoryPort inventory ; // Pattern: Port private final TransactionRunner tx ; // Pattern: Unit of Work Boundary private final OutboxPort outbox ; // Pattern: Transactional Outbox public PlaceOrderUseCase ( OrderRepository orders , InventoryPort inventory , TransactionRunner tx , OutboxPort outbox ) { this . orders = orders ; this . inventory = inventory ; this . tx = tx ; this . outbox = outbox ; } public OrderId handle ( PlaceOrderCommand command ) { return tx . required (() -> { inventory . reserve ( command . customerId (), command . lines ()); Order order = Order . place ( command . customerId (), command . lines ()); // Factory Method orders . save ( order ); outbox . appendAll ( order . pullEvents ()); // Outbox: Event wird mit Order atomar gespeichert return order . id (); }); } }

#Typische Stolperfallen


#35. Enterprise Java V6

Dieses Kapitel zeigt, wie aus Fachlichkeit belastbare Java-Modelle entstehen: Value Objects, Aggregates, Policies, Events und Commands.

#Fachbegriffe

Der größte Fehler in Enterprise-Projekten ist oft nicht technisch, sondern sprachlich: Kunde, Auftrag, Bestellung, Rechnung, Reservierung und Zahlung werden in jedem Team anders verstanden. Ein Domain Model zwingt das Team zu präzisen Begriffen.

#Invarianten

#Value Objects

Value Objects reduzieren Primitive Obsession. Statt überall String customerId und BigDecimal amount zu verwenden, entstehen Typen mit Regeln.

text
public record Money ( BigDecimal amount , Currency currency ) { public Money { if ( amount == null || currency == null ) throw new IllegalArgumentException ( "Money requires amount and currency" ); if ( amount . scale () > 2 ) throw new IllegalArgumentException ( "Money supports cents only" ); } public Money plus ( Money other ) { if ( ! currency . equals ( other . currency )) throw new IllegalArgumentException ( "Currency mismatch" ); return new Money ( amount . add ( other . amount ), currency ); } }

#Aggregate

Ein Aggregate ist keine technische Entity-Sammlung. Es ist eine fachliche Konsistenzgrenze. Im Beispiel darf nur Order entscheiden, ob Positionen, Status und Events zusammen gültig sind.

#Events

Ein Domain Event beschreibt, was fachlich passiert ist. Es ist nicht primär ein technischer Kafka-Record, sondern eine Wahrheit aus der Fachlichkeit.

#Beispiel

text
public final class Order { private final OrderId id ; private final CustomerId customerId ; private final List < OrderLine > lines = new ArrayList <> (); private final List < DomainEvent > events = new ArrayList <> (); private OrderStatus status ; private Order ( OrderId id , CustomerId customerId ) { this . id = id ; this . customerId = customerId ; this . status = OrderStatus . NEW ; } // Pattern: Factory Method - erzeugt nur fachlich gültige Orders. public static Order place ( CustomerId customerId , List < OrderLine > requestedLines ) { if ( requestedLines == null || requestedLines . isEmpty ()) { throw new DomainRuleViolation ( "Eine Bestellung braucht mindestens eine Position" ); } Order order = new Order ( OrderId . newId (), customerId ); requestedLines . forEach ( order :: addLine ); order . events . add ( new OrderPlaced ( order . id , customerId )); return order ; } public void cancel ( String reason ) { if ( status == OrderStatus . INVOICED ) { throw new DomainRuleViolation ( "Fakturierte Bestellung kann nicht storniert werden" ); } status = OrderStatus . CANCELLED ; events . add ( new OrderCancelled ( id , reason )); } }

#36. Enterprise Java V6

Saubere Architektur trennt Fachlichkeit von Framework, Datenbank, Messaging, SOAP und Deployment.

#Problem

In klassischen Enterprise-Systemen landen Controller, EntityManager, SOAP-Client, JMS-Produzent und Geschäftsregeln oft in derselben Klasse. Dadurch ist jeder kleine Fachtest ein halber Integrationstest. Hexagonal Architecture schiebt technische Details an den Rand.

#Architekturregeln

#Ports

text
public interface BillingPort { // Pattern: Port BillingReservation reserveInvoice ( OrderId orderId , Money total ); } public interface OrderRepository { // Pattern: Repository void save ( Order order ); Optional < Order > findById ( OrderId id ); } public interface ClockPort { // Pattern: Dependency Inversion Instant now (); }

#Adapter

text
public final class SoapBillingAdapter implements BillingPort { // Pattern: Adapter + ACL private final LegacyBillingClient client ; private final LegacyBillingMapper mapper ; @Override public BillingReservation reserveInvoice ( OrderId orderId , Money total ) { LegacyInvoiceRequest request = mapper . toLegacyRequest ( orderId , total ); LegacyInvoiceResponse response = client . reserve ( request ); return mapper . toDomainReservation ( response ); } }

#Testbarkeit

Der Use Case kann mit In-Memory-Ports getestet werden. Kein Webserver, keine Datenbank, kein Broker ist nötig.

text
@Test void placeOrderWritesOutboxEvent () { InMemoryOrderRepository orders = new InMemoryOrderRepository (); InMemoryOutbox outbox = new InMemoryOutbox (); PlaceOrderUseCase useCase = new PlaceOrderUseCase ( orders , new AlwaysAvailableInventory (), TransactionRunner . noop (), outbox ); OrderId id = useCase . handle ( sampleCommand ()); assertThat ( orders . findById ( id )). isPresent (); assertThat ( outbox . events ()). hasSize ( 1 ); }

#Entscheidungen


#37. Enterprise Java V6

Spring Boot wird als Laufzeit- und Adapterrahmen verwendet, nicht als Ersatz für fachliche Architektur.

#Rolle von Spring

Spring Boot eignet sich für schnelle produktionsnahe Services mit Autoconfiguration, Actuator, Security-Integration und starkem Ökosystem. Im Architekturmodell sitzt Spring am Rand: Controller, Configuration, Security Filter, Repository-Implementierung und Observability.

#Controller

text
@RestController @RequestMapping ( "/api/orders" ) final class OrderController { // Pattern: Inbound Adapter private final PlaceOrderUseCase placeOrder ; OrderController ( PlaceOrderUseCase placeOrder ) { this . placeOrder = placeOrder ; } @PostMapping ResponseEntity < OrderResponse > place ( @Valid @RequestBody PlaceOrderRequest request ) { OrderId id = placeOrder . handle ( request . toCommand ()); return ResponseEntity . created ( URI . create ( "/api/orders/" + id . value ())) . body ( new OrderResponse ( id . value (), "ACCEPTED" )); } }

#Konfiguration

Spring-Konfiguration verdrahtet Ports und Adapter. Der Use Case bleibt frei von Spring-Annotationen.

text
@Configuration class OrderApplicationConfig { @Bean PlaceOrderUseCase placeOrderUseCase ( OrderRepository orders , InventoryPort inventory , TransactionRunner tx , OutboxPort outbox ) { return new PlaceOrderUseCase ( orders , inventory , tx , outbox ); } }

#Transaktionen

Transaktionsgrenzen gehören in die Application-Schicht oder einen expliziten TransactionRunner. Dadurch bleibt klar, welcher Use Case atomar sein muss.

#Betrieb

#Fehlerbild


#38. Enterprise Java V6

Jakarta EE zeigt Enterprise-Standardisierung mit CDI, JTA, JAX-RS, Persistence, Security und Batch.

#Rolle von Jakarta EE

Jakarta EE ist besonders stark, wenn ein Unternehmen Standards, zertifizierte Runtime, Portabilität und klassische Enterprise-Fähigkeiten wie CDI, JTA, JAX-RS, Jakarta Persistence, Messaging und Batch bündeln möchte.

#JAX-RS Resource

text
@Path ( "/orders" ) @Consumes ( MediaType . APPLICATION_JSON ) @Produces ( MediaType . APPLICATION_JSON ) public class OrderResource { // Pattern: Inbound Adapter @Inject PlaceOrderUseCase placeOrder ; @POST public Response place ( PlaceOrderRequest request , @Context UriInfo uriInfo ) { OrderId id = placeOrder . handle ( request . toCommand ()); URI location = uriInfo . getAbsolutePathBuilder (). path ( id . value ()). build (); return Response . created ( location ). entity ( new OrderResponse ( id . value (), "ACCEPTED" )). build (); } }

#CDI

CDI übernimmt Dependency Injection und Scopes. Auch hier sollte die Domain keine CDI-Annotationen benötigen.

#JTA

text
@ApplicationScoped public class JakartaTransactionRunner implements TransactionRunner { // Pattern: Unit of Work @Transactional public < T > T required ( Supplier < T > work ) { return work . get (); } }

#Batch

Jakarta Batch eignet sich für kontrollierte, wiederanlaufbare Verarbeitung großer Datenmengen. Das Praxisprojekt nutzt Batch für nächtliche Rechnungsabgleiche.

#Vergleich


#39. Enterprise Java V6

Quarkus und MicroProfile verbinden Enterprise Java APIs mit cloud-nativer Laufzeit, schnellen Starts und Kubernetes-Nähe.

#Rolle

Quarkus eignet sich, wenn schnelle Startup-Zeiten, Container, Kubernetes/OpenShift, geringe Speicherlast und MicroProfile-nahe APIs wichtig sind. Die Domain bleibt auch hier unabhängig.

#Resource

text
@Path ( "/orders" ) @Consumes ( MediaType . APPLICATION_JSON ) @Produces ( MediaType . APPLICATION_JSON ) public class QuarkusOrderResource { // Pattern: Inbound Adapter private final PlaceOrderUseCase placeOrder ; public QuarkusOrderResource ( PlaceOrderUseCase placeOrder ) { this . placeOrder = placeOrder ; } @POST public Response place ( PlaceOrderRequest request ) { OrderId id = placeOrder . handle ( request . toCommand ()); return Response . accepted ( new OrderResponse ( id . value (), "ACCEPTED" )). build (); } }

#Fault Tolerance

text
@ApplicationScoped class InventoryClient implements InventoryPort { // Pattern: Adapter @Timeout ( 750 ) @Retry ( maxRetries = 2 ) @CircuitBreaker ( requestVolumeThreshold = 20 , failureRatio = 0.5 ) public void reserve ( CustomerId customerId , List < OrderLine > lines ) { // HTTP call zum Inventory-System } }

#Config

MicroProfile Config erlaubt saubere externe Konfiguration. Keine Secrets im Code, keine Umgebungsspezifika in der Domain.

#Health

Liveness prüft, ob der Prozess lebt. Readiness prüft, ob Traffic angenommen werden darf. Startup prüft lange Initialisierungen.

#Trade-offs


#40. Enterprise Java V6

Eine große Entscheidungsmatrix hilft, Framework, Library, Spezifikation und Tool sauber zu unterscheiden.

#Entscheidungsmodell

Eine Library löst meist ein fokussiertes Problem. Ein Framework gibt Struktur, Laufzeitmodell und Integrationspunkte vor. Eine Spezifikation definiert Verträge, die mehrere Implementierungen erfüllen können. Ein Tool unterstützt Build, Test, Analyse oder Betrieb.

#Matrix

#Regeln

#Beispiel


#41. Enterprise Java V6

Enterprise-Systeme scheitern häufig nicht am Code, sondern an falschen Konsistenzannahmen.

#Transaktionsarten

#Outbox

Outbox speichert ein Event in derselben Transaktion wie den fachlichen Zustand. Ein separater Prozess veröffentlicht später zuverlässig.

text
public interface OutboxPort { // Pattern: Transactional Outbox Port void append ( DomainEvent event ); void appendAll ( List < DomainEvent > events ); } public final class OutboxRelay { // Pattern: Polling Publisher private final OutboxStore store ; private final MessagePublisher publisher ; public void publishPending () { for ( OutboxMessage msg : store . lockNextBatch ( 100 )) { publisher . publish ( msg . topic (), msg . payload (), msg . idempotencyKey ()); store . markPublished ( msg . id ()); } } }

#Saga

Eine Saga koordiniert mehrere lokale Transaktionen. Bei Fehlern wird nicht zurückgerollt wie in einer DB, sondern kompensiert.

#Idempotenz

Jeder Consumer muss Mehrfachzustellung aushalten. Dafür braucht man Idempotency Keys, deduplizierende Tabellen oder fachliche natürliche Schlüssel.

#Code

text
public final class OrderSaga { // Pattern: Saga Orchestrator public void on ( OrderPlaced event ) { try { billing . reserveInvoice ( event . orderId ()); inventory . commitReservation ( event . orderId ()); } catch ( BillingUnavailable ex ) { inventory . releaseReservation ( event . orderId ()); // Kompensation orders . markPaymentPending ( event . orderId ()); } } }

#Warnung


#42. Enterprise Java V6

Neue Enterprise-Java-Systeme müssen oft mit alten Systemen kommunizieren, ohne deren Modellfehler zu übernehmen.

#Prinzip

Legacy-Integration braucht eine Schutzschicht. Die neue Domain darf nicht direkt WSDL-Namen, Stored-Procedure-Parameter oder alte Statuscodes übernehmen.

#SOAP

Bei SOAP ist Contract-First wichtig: WSDL, XSD, Bindings und Prozessschritte werden dokumentiert. Der Adapter übersetzt SOAP-Fehler in fachliche Fehler.

text
public final class LegacyBillingMapper { // Pattern: Anti-Corruption Layer LegacyInvoiceRequest toLegacyRequest ( OrderId orderId , Money total ) { LegacyInvoiceRequest request = new LegacyInvoiceRequest (); request . setExternalOrderNo ( orderId . value ()); request . setAmountInCent ( total . amount (). movePointRight ( 2 ). longValueExact ()); request . setCurrency ( total . currency (). getCurrencyCode ()); return request ; } }

#Batch

Batch eignet sich für große Mengen, Wiederanlauf, fachliche Kontrollpunkte und Nachtverarbeitung. Moderne Batchjobs sollten idempotent und beobachtbar sein.

#DB

Direkter Legacy-DB-Zugriff ist riskant. Besser sind stabile Views, APIs oder klar dokumentierte Stored Procedures mit Tests.

#File

Dateischnittstellen brauchen Schema, Zeichensatz, Zeilenformat, Fehlerdatei, Reprocessing und Archivierung.

#Mapping


#43. Enterprise Java V6

REST APIs sind langfristige Verträge. Entscheidend sind Stabilität, Fehlerverträge, Versionierung und Konsistenz.

#API als Vertrag

Eine interne API kann genauso kritisch sein wie eine öffentliche API. Breaking Changes erzeugen Abhängigkeitsschäden in anderen Teams.

#Ressourcen

#Fehler

text
{ "type" : "https://errors.example.com/order/invalid-state" , "title" : "Order cannot be cancelled" , "status" : 409 , "detail" : "Order ORD-4711 is already invoiced." , "traceId" : "4e7f9a2c8d" , "code" : "ORDER_ALREADY_INVOICED" }

#Versionierung

Versionierung ist kein Ersatz für Kompatibilität. Neue optionale Felder sind meist besser als harte Brüche. Entfernen ist gefährlicher als Ergänzen.

#Beispiel

text
public record PlaceOrderRequest ( String customerId , List < OrderLineRequest > lines , String idempotencyKey ) { PlaceOrderCommand toCommand () { return new PlaceOrderCommand ( new CustomerId ( customerId ), lines . stream (). map ( OrderLineRequest :: toDomain ). toList (), idempotencyKey ); } }

#Checkliste


#44. Enterprise Java V6

Messaging macht Systeme lose gekoppelt, aber nur mit klaren Verträgen, Idempotenz und Beobachtbarkeit robust.

#Arten

#Event Design

Events brauchen fachlichen Namen, Version, Zeit, Korrelation und Idempotency Key. Technische Payloads ohne Kontext sind schwer wartbar.

text
public record OrderPlacedEventV1 ( String eventId , String traceId , String orderId , String customerId , Instant occurredAt , List < Line > lines ) implements DomainEvent {}

#Outbox

Outbox ist der Default, wenn ein DB-Zustand und ein Event zusammengehören. Direct publish im Use Case ist fast immer riskanter.

#Consumer

text
public final class BillingOrderPlacedConsumer { // Pattern: Idempotent Consumer public void handle ( OrderPlacedEventV1 event ) { if ( processedEvents . alreadyProcessed ( event . eventId ())) return ; billing . createDraftInvoice ( event . orderId (), event . customerId ()); processedEvents . markProcessed ( event . eventId ()); } }

#Fehler

Fehlerstrategie: Retry für temporäre Fehler, Dead Letter Queue für nicht verarbeitbare Nachrichten, Alerting bei wachsendem Lag.

#Vergleich


#45. Enterprise Java V6

Security ist nicht nur Login. Moderne Enterprise-Systeme brauchen Identität, Rechte, Secrets, Netzwerkgrenzen, Audit und sichere Defaults.

#Modell

Zero Trust bedeutet: Kein Netzwerkbereich wird automatisch vertraut. Jede Anfrage braucht Identität, Kontext, Policy und Nachvollziehbarkeit.

#AuthN/AuthZ

#Service-to-Service

Für interne Kommunikation werden mTLS, kurzlebige Tokens, Audience-Prüfung und minimale Berechtigungen benötigt.

text
public final class AuthorizationPolicy { // Pattern: Policy/Strategy public boolean mayCancel ( Order order , Principal principal ) { return principal . hasRole ( "ORDER_MANAGER" ) && ! order . isInvoiced (); } }

#Secrets

Secrets gehören nicht in Git, nicht in Images und nicht in Logs. Sie kommen aus Secret Manager, Kubernetes/OpenShift Secrets oder Vault-ähnlichen Systemen.

#Audit

Audit muss fachliche Aktion, Akteur, Zeitpunkt, Ergebnis, TraceId und relevante Ressource enthalten.

#Fehler


#46. Enterprise Java V6

Ein Enterprise-System ist erst fertig, wenn Betrieb und Fehlerdiagnose mitgedacht sind.

#Signale

#Trace

TraceId und CorrelationId müssen durch REST, Messaging, Batch und SOAP weitergegeben werden.

text
public final class TraceContext { // Pattern: Context Object private final String traceId ; private final String correlationId ; public Map < String , String > asHeaders () { return Map . of ( "X-Trace-Id" , traceId , "X-Correlation-Id" , correlationId ); } }

#Metriken

#Logs

Logs sind strukturiert, maschinenlesbar und enthalten keine Secrets. Stacktraces ohne Kontext reichen nicht.

#Runbook

#SLO

Ein gutes SLO ist fachlich: 99,5% der Bestellungen werden innerhalb von 2 Sekunden angenommen; 99,9% der Outbox-Events werden innerhalb von 60 Sekunden publiziert.


#47. Enterprise Java V6

Tests müssen zur Architektur passen: schnell in der Mitte, realistisch an den Rändern, wenige aber wertvolle E2E-Flows.

#Strategie

Die Testpyramide wird im Enterprise-Kontext oft falsch verstanden. Viele langsame E2E-Tests ersetzen keine guten Domain- und Use-Case-Tests.

#Unit

text
@Test void orderWithoutLinesIsRejected () { assertThrows ( DomainRuleViolation . class , () -> Order . place ( new CustomerId ( "C-1" ), List . of ())); }

#Integration

Integrationstests prüfen Adapter gegen echte Infrastruktur: PostgreSQL, Kafka, JMS-kompatible Broker, HTTP WireMock oder Testcontainers.

#Contract

Contract Tests verhindern, dass Producer und Consumer beim API-/Event-Vertrag auseinanderlaufen.

#E2E

E2E ist teuer und fragil. Deshalb nur wenige kritische Happy Paths und ausgewählte Fehlerpfade.

#Architekturtests

text
@AnalyzeClasses ( packages = "com.aydinsude.enterprise" ) class ArchitectureRulesTest { @ArchTest static final ArchRule domain_has_no_framework_dependency = noClasses (). that (). resideInAPackage ( "..domain.." ). should () . dependOnClassesThat (). resideInAnyPackage ( "org.springframework.." , "jakarta.." , "org.hibernate.." ); }

#48. Enterprise Java V6

Enterprise Java muss verschiedene Betriebsumgebungen erklären können: VM, Bare Metal, Kubernetes und OpenShift.

#Vergleich

#VM

VMs eignen sich für klassische Enterprise-Deployments, Migrationen und Systeme mit niedriger Änderungsrate.

#Bare Metal

Bare Metal ist sinnvoll, wenn Hardwarekontrolle, spezielle Latenz oder Kosteneffizienz bei hoher Auslastung wichtig sind.

#Kubernetes

Kubernetes bringt Scheduling, Service Discovery, Self-Healing, Secrets, ConfigMaps und Rollouts.

#OpenShift

OpenShift ergänzt Kubernetes um Enterprise-Funktionen wie Security-Konventionen, Routes, Build/Deployment-Integration, Operatoren und Plattform-Governance.

#Strategie

text
apiVersion : apps/v1 kind : Deployment metadata : name : order-service spec : replicas : 3 template : spec : containers : - name : order-service image : registry.example.com/order-service:1.0.0 readinessProbe : httpGet : path : /actuator/health/readiness port : 8080 resources : requests : cpu : "250m" memory : "512Mi"

#49. Enterprise Java V6

Refactoring wird greifbar, wenn man Ausgangscode und Zielcode nebeneinander sieht.

#Vorgehen

#Monster Service

text
public void createOrder ( Map < String , Object > input ) { // schlecht: Validierung, SQL, SOAP, Statuslogik und Eventing in einer Methode if ( input . get ( "customer" ) == null ) throw new RuntimeException ( "missing" ); jdbc . update ( "insert into orders ..." ); soapClient . reserveInvoice ( input ); jms . send ( "ORDER_CREATED" , input ); }
text
public OrderId handle ( PlaceOrderCommand command ) { return tx . required (() -> { Order order = Order . place ( command . customerId (), command . lines ()); orders . save ( order ); outbox . appendAll ( order . pullEvents ()); return order . id (); }); }

#JDBC Spaghetti

SQL darf im Adapter bleiben, aber nicht die Domain-Sprache ersetzen. Repository-Methoden sollen fachlich lesbar sein.

#Mapping

Manuelles Ad-hoc-Mapping quer durch Services erzeugt Fehler. MapStruct oder explizite Mapper bündeln die Übersetzung.

#Exception Handling

#Check


#50. Enterprise Java V6

Dieses Abschlusskapitel fasst V3 als prüfbaren Senior-Lernpfad zusammen.

#Senior Checkliste

#Lernplan

#Review-Fragen

#Praxisaufgaben

#Abschluss

V3 ist als Lernbuch, Nachschlagewerk und Projektbasis gedacht: lesen, ausprobieren, im Code markieren, im Team diskutieren und als Vorlage für echte Modernisierung verwenden.


#51. Enterprise Java V6

End-to-end Ablauf vom Portal bis Buchhaltung, inklusive fachlicher Zuständigkeiten, Schnittstellen, Fehlerfällen und Betriebsnachweisen.

#Fachlicher Ablauf

Order-to-Cash beginnt nicht im Controller, sondern bei einer fachlichen Absicht: Ein Kunde will etwas bestellen. Danach folgen Preisprüfung, Limitprüfung, Bestandsreservierung, Rechnungslogik, Event-Publish und Betriebsnachweis. In Enterprise-Projekten ist wichtig, jeden Schritt einem System Owner und einer Transaktionsgrenze zuzuordnen.

#Technischer Schnitt

Der rote Faden in V6 ist ein Vertikalschnitt. Jede Schicht bekommt nur die Verantwortung, die sie tragen kann: Portal/BFF für Darstellung, Application Service für Use Case, Domain für Invarianten, Adapter für Fremdsysteme, Outbox für technische Übergabe.

#Beispielcode

text
package at.aydinsude.enterprise.order.application ; import at.aydinsude.enterprise.order.domain.* ; import java.time.Clock ; // Pattern: Application Service - orchestriert genau einen fachlichen Use Case. // Pattern: Port-and-Adapter - nutzt RepositoryPort und EventPublisherPort statt Framework-Abhängigkeiten. public final class PlaceOrderUseCase { private final OrderRepositoryPort orders ; private final CustomerRiskPort customerRisk ; private final EventPublisherPort events ; private final Clock clock ; public PlaceOrderUseCase ( OrderRepositoryPort orders , CustomerRiskPort customerRisk , EventPublisherPort events , Clock clock ) { this . orders = orders ; this . customerRisk = customerRisk ; this . events = events ; this . clock = clock ; } public OrderId handle ( PlaceOrderCommand command ) { if ( orders . existsByIdempotencyKey ( command . idempotencyKey ())) { return orders . findOrderIdByIdempotencyKey ( command . idempotencyKey ()); } customerRisk . assertCustomerMayOrder ( command . customerId (), command . total ()); Order order = Order . place ( command . customerId (), command . lines (), command . idempotencyKey (), clock . instant ()); orders . save ( order ); events . publishAll ( order . pullDomainEvents ()); return order . id (); } }

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#52. Enterprise Java V6

Aggregates, Entities, Value Objects, Domain Events und Repositories als taktisches Modell für robuste Enterprise-Domänen.

#Aggregate statt Datencontainer

Ein Aggregate schützt eine Konsistenzgrenze. Es ist nicht einfach eine JPA-Entity mit Gettern und Settern. Im Order-Aggregate liegen Regeln wie Mindestmenge, Statusübergänge, Kreditlimit-Reaktion und Domain Events.

#Value Objects

Value Objects wie Money, Quantity und CustomerId sind bewusst klein, unveränderlich und fachlich benannt. Dadurch verschwinden viele primitive String-/BigDecimal-Fehler.

#DDD-Checkliste

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#53. Enterprise Java V6

Fachliche Fehler, technische Fehler, HTTP Problem Details, SOAP Faults und stabile Fehlerverträge im Großsystem.

#Fehlerarten trennen

Ein fachlicher Konflikt ist kein technischer Systemfehler. Wenn ein Kunde kein Limit hat, ist das etwas anderes als ein Datenbank-Timeout. Diese Trennung muss sich in Code, API-Vertrag, Logging und Monitoring zeigen.

#Problem Details

REST-APIs sollten stabile Fehlercodes und maschinenlesbare Details liefern. SOAP-Systeme brauchen entsprechende Fault-Strukturen. Wichtig ist, dass interne Klassennamen nicht nach außen leaken.

#Beispielcode

text
package at.aydinsude.enterprise.api ; import java.net.URI ; import java.util.Map ; // Pattern: Error Contract - technische Darstellung ist stabil, Domain bleibt unabhängig. public record ProblemDetails ( URI type , String title , int status , String detail , String instance , Map < String , Object > extensions ) { public static ProblemDetails businessConflict ( String code , String detail , String traceId ) { return new ProblemDetails ( URI . create ( "https://errors.example.com/enterprise/" + code ), "Business conflict" , 409 , detail , traceId , Map . of ( "code" , code , "retryable" , false )); } }

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#54. Enterprise Java V6

Warum Enterprise-Systeme Wiederholung als Normalfall behandeln müssen: Idempotency Keys, deduplication, Outbox und Replay.

#Warum Exactly Once meist eine Illusion ist

Netzwerke, Broker und Datenbanken liefern selten Ende-zu-Ende-Exactly-Once über alle Grenzen. Robuste Enterprise-Systeme bauen deshalb auf mindestens-einmal-Zustellung plus Idempotenz, Deduplication und Reconciliation.

#Idempotency Key

Der Idempotency Key gehört zu einem fachlichen Kontext: Kunde, Operation, Zeitraum und Payload-Fingerprint. Derselbe Schlüssel mit anderer Payload muss als Missbrauch oder Clientfehler behandelt werden.

#Beispielcode

text
package at.aydinsude.enterprise.order.application ; import java.time.Instant ; import java.util.Optional ; // Pattern: Idempotent Consumer - Wiederholung ist erwartet, nicht außergewöhnlich. public final class IdempotencyService { private final IdempotencyStore store ; public IdempotencyService ( IdempotencyStore store ) { this . store = store ; } public < T > T executeOnce ( String key , Class < T > resultType , java . util . function . Supplier < T > action ) { Optional < T > previous = store . findSuccessfulResult ( key , resultType ); if ( previous . isPresent ()) { return previous . get (); } store . markStarted ( key , Instant . now ()); try { T result = action . get (); store . markSucceeded ( key , result , Instant . now ()); return result ; } catch ( RuntimeException ex ) { store . markFailed ( key , ex . getClass (). getSimpleName (), Instant . now ()); throw ex ; } } }

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#55. Enterprise Java V6

Optimistic Locking, pessimistische Sperren, Audit-Spalten, technische Historisierung und fachliche Nachvollziehbarkeit.

#Optimistic Locking

Optimistic Locking passt, wenn Konflikte selten sind und Benutzer oder Prozesse wiederholen können. Die Version-Spalte schützt vor Lost Updates.

#Audit und Historie

Audit-Spalten beantworten technische Fragen. Fachliche Historie beantwortet Business-Fragen. Beide sollten nicht verwechselt werden.

#Entscheidungstabelle

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#56. Enterprise Java V6

Schema-Versionierung, Rollback-Denken, expand/contract Migrationen und Datenkorrekturen ohne Produktionsstillstand.

#Expand/Contract

Produktionsmigrationen sollten kompatibel ausgerollt werden. Erst erweitern, dann Code umstellen, dann alte Struktur entfernen.

#Flyway vs Liquibase

Flyway ist besonders einfach für lineare SQL-Versionen. Liquibase ist stark bei deklarativen Changesets und komplexeren Deployment-Prozessen. Entscheidend ist weniger das Tool als die Disziplin im Prozess.

#Migrationsbeispiel

text
-- V20260707_01__add_order_audit.sql
ALTER TABLE orders ADD COLUMN created_by VARCHAR(120);
ALTER TABLE orders ADD COLUMN trace_id VARCHAR(80);

UPDATE orders SET created_by = 'migration', trace_id = 'baseline'
WHERE created_by IS NULL;

ALTER TABLE orders ALTER COLUMN created_by SET NOT NULL;

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#57. Enterprise Java V6

Schreibmodell sauber halten, Lesemodelle gezielt aufbauen, Suche und Reporting entkoppeln.

#Write Model schützen

CQRS bedeutet nicht automatisch Event Sourcing. Oft reicht es, ein sauberes Write Model mit separaten Read Models für Suche, Listen und Reporting zu kombinieren.

#Read Model Rebuild

Ein gutes Lesemodell kann neu aufgebaut werden. Deshalb braucht es Projektion, Rebuild-Prozess, Versionierung und Messung von Lag.

#Matrix

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#58. Enterprise Java V6

Warum ein gut geschnittener Modular Monolith oft der bessere Zwischenschritt vor Microservices ist.

#Warum modularer Monolith

Ein Modular Monolith hält Deployment einfach, erzwingt aber fachliche Grenzen. Für viele Modernisierungen ist er der beste Schritt zwischen Legacy-Monolith und verteilten Microservices.

#Spring Modulith Idee

Module werden sichtbar, Abhängigkeiten prüfbar und Ereignisse innerhalb des Monolithen besser modelliert.

#Architekturtest

text
package at.aydinsude.enterprise.architecture ; import com.tngtech.archunit.core.importer.ClassFileImporter ; import com.tngtech.archunit.lang.syntax.ArchRuleDefinition ; // Pattern: Fitness Function - Architekturregel als automatisierter Test. class ModuleBoundaryTest { void domainMustNotDependOnAdapters () { var classes = new ClassFileImporter (). importPackages ( "at.aydinsude.enterprise" ); ArchRuleDefinition . noClasses () . that (). resideInAPackage ( "..domain.." ) . should (). dependOnClassesThat (). resideInAPackage ( "..adapter.." ) . check ( classes ); } }

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#59. Enterprise Java V6

Jakarta Data als Standardisierungsschritt, Repository-Abstraktion und portabler Umgang mit Persistenz.

#Repository nicht mit CRUD verwechseln

Ein Repository ist fachlich motiviert. Es speichert und lädt Aggregates oder Projektionen. Eine generische CRUD-Schnittstelle ist in komplexen Domänen oft zu schwach.

#Jakarta Data

Jakarta Data standardisiert Repository-ähnliche Persistenzkonzepte innerhalb der Jakarta-EE-Welt. V6 behandelt es als Standardisierungsoption, nicht als Zwang für jede Architektur.

#Portabilität

Portabilität entsteht nicht nur durch APIs, sondern durch disziplinierte Grenzen: Domain kennt keine Provider-Annotationen, Queries sind gekapselt, Integrationsverträge sind getestet.

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#60. Enterprise Java V6

Quarkus im JVM- und Native-Modus, Build-Time-Metadaten, Container-Images und Betriebsentscheidungen.

#JVM Mode vs Native

JVM Mode ist oft die beste Wahl für Entwicklung, Debugging und maximale Kompatibilität. Native Mode kann bei Startup und Footprint helfen, verlangt aber konsequente Tests mit echten Extensions.

#Build-Time Ansatz

Quarkus verschiebt viel Arbeit in die Build-Zeit. Das ist stark für Container, aber man muss verstehen, welche Reflection, Proxies und Ressourcen im Native Image verfügbar sind.

#Betriebsentscheidung

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#61. Enterprise Java V6

Virtual Threads sinnvoll einsetzen, klassische Pools verstehen und Blocking/Nonblocking sauber unterscheiden.

#Grundregel

Virtual Threads machen blockierenden Code skalierbarer, aber sie vergrößern nicht automatisch Datenbankpools, Broker-Limits oder Remote-System-Kapazität.

#Typischer Fehler

Ein Team erhöht parallele Requests massiv, aber lässt den DB-Pool bei 20 Verbindungen. Ergebnis: Warteschlangen wandern nur an eine andere Stelle.

#Beispiel

text
try ( var executor = java . util . concurrent . Executors . newVirtualThreadPerTaskExecutor ()) { var futures = customerIds . stream () . map ( id -> executor . submit (() -> customerClient . loadCustomer ( id ))) . toList (); for ( var future : futures ) { handle ( future . get ()); } } // Wichtig: Remote-Limits, Timeouts und Bulkheads bleiben erforderlich.

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#62. Enterprise Java V6

Wann reaktive Programmierung hilft, wann sie nur Komplexität erzeugt und wie man beide Modelle bewertet.

#Imperativ ist nicht altmodisch

Die meisten CRUD- und Use-Case-Flows sind imperativ besser lesbar. Reactive lohnt sich besonders bei Streams, Backpressure und sehr hoher IO-Konkurrenz.

#Grenzen ziehen

Eine reaktive Transportstrecke darf nicht die Domain verkomplizieren. Der Kern kann synchron und klar bleiben, während Adapter reactive arbeiten.

#Entscheidung

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#63. Enterprise Java V6

Gateway, Backend-for-Frontend, Portal, Session-Kontext, Token Relay und Anti-Corruption Layer.

#BFF als UI-Adapter

Ein Backend-for-Frontend aggregiert Daten für eine konkrete Oberfläche. Es sollte keine zentrale Fachlogik übernehmen, sonst entsteht ein neuer Monolith am Rand.

#Gateway ist Infrastruktur

Gateway-Funktionen sind Routing, TLS, Rate Limit, AuthN-Vorprüfung und Traffic Policies. Es ersetzt keine fachliche Autorisierung im Service.

#Portal-Integration

Bei Portalen ist Kontext wichtig: Benutzer, Mandant, Rolle, Session, Sprache, Consent und Audit müssen über Systemgrenzen nachvollziehbar bleiben.

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#64. Enterprise Java V6

Workflow-Design mit zentralem Orchestrator oder dezentraler Choreografie, inklusive Kompensationen.

#Orchestrierung

Ein Orchestrator macht Prozesszustand sichtbar und eignet sich für lange, regelreiche Abläufe. Dafür entsteht eine zentrale Komponente.

#Choreografie

Choreografie koppelt weniger zentral, kann aber schwerer zu debuggen sein. Ohne gute Observability wird sie schnell unverständlich.

#Kompensation

Eine Saga rollt nicht technisch zurück. Sie führt fachliche Gegenaktionen aus, zum Beispiel Reservierung freigeben oder Rechnung stornieren.

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#65. Enterprise Java V6

Enterprise-Integration ist nicht nur REST: Dateien, SFTP, CSV, EDI, Quarantäne und Reprocessing.

#Dateien bleiben Enterprise-Realität

Viele Systeme liefern weiterhin CSV, Fixed Width, EDI oder XML per SFTP. Moderne Architektur muss diese Welt kapseln, nicht ignorieren.

#Quarantäne

Fehlerhafte Dateien dürfen nicht verschwinden. Sie brauchen Quarantäne, Fehlerbericht, manuelles oder automatisches Reprocessing und Audit.

#Importfluss

text
landing/
  inbound/ORDERS_20260707_001.csv
  processing/ORDERS_20260707_001.csv
  quarantine/ORDERS_20260707_001.error.json
  archive/2026/07/07/ORDERS_20260707_001.csv

Jeder Statuswechsel wird mit Checksumme, TraceId und fachlicher BatchId dokumentiert.

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#66. Enterprise Java V6

Große Reports, Exporte, Nachtläufe, Datenfenster, Wiederanlauf und fachlicher Abgleich.

#Batch-Fenster

Batchjobs haben fachliche Zeitfenster. Ein Nachtlauf darf nicht blind Daten lesen, während der Tagbetrieb dieselben Daten verändert.

#Restartability

Ein Batch muss wiederanlaufbar sein. Chunk-Größe, Checkpoint, Idempotenz und fachliche Abstimmung entscheiden über Stabilität.

#Reporting

Große Reports gehören nicht unkontrolliert auf die OLTP-Datenbank. Read Replicas, Snapshots oder Reporting Stores schützen den Kernbetrieb.

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#67. Enterprise Java V6

Produktionsnahe Security-Architektur mit Identity Provider, mTLS, Secret Rotation, Audit Trail und Least Privilege.

#Produktionsnahe Security

Security besteht nicht nur aus Login. Relevant sind Identity Provider, Service-zu-Service-Vertrauen, Secret Rotation, Audit, Policy Enforcement und Incident Response.

#mTLS und Token

mTLS beantwortet, welcher Dienst spricht. Token beantwortet, in welchem Benutzer-/Clientkontext gehandelt wird. Beides ersetzt einander nicht.

#Audit Trail

Ein guter Audit Trail dokumentiert fachliche Aktion, technische Identität, Benutzerkontext, Zeitpunkt, Ergebnis und Korrelation.

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#68. Enterprise Java V6

BOMs, Parent-POMs, Dependency Constraints, Plugin Management und Upgrade-Kontrolle im Enterprise-Team.

#Version Governance

Ohne zentrale Version Governance entstehen verschiedene Spring-, Jackson-, Netty-, Hibernate- und Plugin-Stände im selben Unternehmen. Das macht Security Fixes langsam.

#BOM und Plugin Management

BOMs steuern Bibliotheksversionen. Plugin Management steuert Build-Verhalten. Beides gehört in einen nachvollziehbaren Parent oder Build-Standard.

#POM-Auszug

text
<project> <dependencyManagement> <dependencies> <dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-dependencies </artifactId> <version> ${spring.boot.version} </version> <type> pom </type> <scope> import </scope> </dependency> </dependencies> </dependencyManagement> <build> <pluginManagement> <plugins> <plugin> <groupId> org.apache.maven.plugins </groupId> <artifactId> maven-enforcer-plugin </artifactId> <version> ${maven.enforcer.version} </version> </plugin> </plugins> </pluginManagement> </build> </project>

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#69. Enterprise Java V6

SBOM, CVE-Prozess, Lizenzprüfung, Reproduzierbarkeit und sichere Artefaktkette.

#SBOM

Eine Software Bill of Materials macht Abhängigkeiten maschinenlesbar. Sie ist Grundlage für CVE-Abgleich, Lizenzprüfung und Lieferkettennachweise.

#Lizenzrisiko

Nicht jede Open-Source-Lizenz passt zu jedem Produktmodell. Copyleft, Netzwerk-Copyleft, Notice-Pflichten und transitive Abhängigkeiten müssen geprüft werden.

#Pipeline-Evidence

Build-Logs, SBOM, Signatur, Testreport und Freigabeentscheidung sollten als Liefernachweis archiviert werden.

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#70. Enterprise Java V6

Build-Pipelines, Qualitätsgates, Artefaktpromotion, Umgebungen und Deployment-Automatisierung.

#Pipeline-Stufen

Eine gute Pipeline kompiliert nicht nur. Sie prüft Architektur, Tests, Security, Lizenz, SBOM, Container-Scan, Deployment und Smoke Tests.

#Promotion statt Rebuild

Ein Artefakt sollte durch Umgebungen promotet werden. Für Stage und Prod neu zu bauen erzeugt schwer nachvollziehbare Unterschiede.

#CI Beispiel

text
name : enterprise-java-ci on : [ push , pull_request ] jobs : build : runs-on : ubuntu-latest steps : - uses : actions/checkout@v4 - uses : actions/setup-java@v4 with : distribution : temurin java-version : '25' cache : maven - run : ./mvnw -B -DskipITs=false verify - run : ./mvnw -B cyclonedx:makeAggregateBom - run : ./mvnw -B org.owasp:dependency-check-maven:check

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#71. Enterprise Java V6

Namespaces, Routes, Services, DeploymentConfig/Deployment, ConfigMaps, Secrets, HPA und Betriebsgrenzen.

#Produktionsschnitt

OpenShift ist nicht nur ein Ort für Pods. Entscheidend sind Namespaces, Ressourcenlimits, Probes, Routes, Secrets, Network Policies, Operators und Betriebsprozesse.

#Java im Container

Heap, Metaspace, Threadanzahl, CPU Limits und GC müssen zusammen betrachtet werden. Falsche Limits erzeugen OOMKills oder schlechte Latenz.

#Deployment

text
apiVersion : apps/v1 kind : Deployment metadata : name : order-service spec : replicas : 3 selector : matchLabels : { app : order-service } template : metadata : labels : { app : order-service } spec : containers : - name : app image : registry.example.com/order-service:1.0.0 ports : [{ containerPort : 8080 }] envFrom : - configMapRef : { name : order-service-config } - secretRef : { name : order-service-secrets } readinessProbe : httpGet : { path : /actuator/health/readiness , port : 8080 } livenessProbe : httpGet : { path : /actuator/health/liveness , port : 8080 } resources : requests : { cpu : "250m" , memory : "512Mi" } limits : { cpu : "1000m" , memory : "1024Mi" }

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#72. Enterprise Java V6

Von Metriken zu Entscheidungen: SLO, Error Budget, Burn Rate, Incident-Triage und Postmortem.

#SLI und SLO

Ein SLI misst ein relevantes Symptom. Ein SLO setzt das Ziel. Error Budget macht sichtbar, wie viel Risiko für Änderungen verfügbar ist.

#Incident Triage

Bei Störungen zählt zuerst Impact: Wer ist betroffen, wie stark, seit wann, gibt es Workaround und wer entscheidet über Rollback?

#Runbook-Fragen

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#73. Enterprise Java V6

Realistische Test-Labs mit Datenbank, Message Broker, Consumer Contracts, WireMock und Fehler-Injektion.

#Testcontainers Lab

Integrationstests gegen echte Datenbanken und Broker finden Fehler, die Mocks nicht sehen: SQL-Dialekt, Transaktionen, Serialization, Consumer Lag.

#Contract Tests

Consumer Contracts verhindern, dass Provider Änderungen ausrollt, die Clients brechen. Sie sind besonders wertvoll bei Portal/BFF/API-Landschaften.

#Chaos im Kleinen

Timeouts, 500er, Deadlocks, Broker-Neustarts und langsame Antworten sollten kontrolliert im Test-Lab vorkommen.

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#74. Enterprise Java V6

Schrittweise Migration von EAR/WAR/EJB/SOAP/JMS/JSP zu modularen Java-Services auf Container-Plattformen.

#Inventory der Altlast

Vor Migration werden Module, Deployments, EJBs, SOAP-Operationen, JMS-Queues, Datenbankzugriffe, JSP-Seiten, Batchjobs und Betriebsjobs inventarisiert.

#Strangler

Nicht alles wird neu geschrieben. Neue Vertikalschnitte übernehmen gezielt Traffic, während Legacy-Systeme über Adapter weiterlaufen.

#Cutover-Kriterien

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#75. Enterprise Java V6

Fragen, Aufgaben und Bewertungsraster für echte Senior-Gespräche, Reviews und Projektentscheidungen.

#Prüfungslogik

Senior-Niveau bedeutet nicht, alle Framework-APIs auswendig zu kennen. Wichtig ist, Trade-offs zu erkennen, Grenzen zu ziehen, Risiken zu dokumentieren und Code als Beweis zu liefern.

#Interviewfragen

Warum Saga statt JTA? Wann Modular Monolith statt Microservices? Wie verhindert man doppelte Events? Wie migriert man ein SOAP-Portal ohne Big Bang? Wie erkennt man, dass eine Architekturentscheidung funktioniert?

#Bewertungsraster

#Praxisübertragung auf das V4-Beispielprojekt

#Entscheidung

Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.

#Code-Nachweis

Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md .

#Betrieb

Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.

#Typische Fehlerbilder


#76. Enterprise Reference Architecture Map

Ein Gesamtbild für produktionsreife Java-Enterprise-Landschaften: Domäne, Integrationen, Daten, Plattform, Security, Observability und Governance werden als zusammenhängende Karte verstanden.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Enterprise Reference Architecture Map als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Enterprise Reference Architecture Map - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class ReferenceArchitectureMap { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# enterprise-reference-architecture-map.yaml owner : enterprise-architecture chapter : 76 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#77. Architecture Governance, Fitness Functions und ADR Betrieb

Wie Architekturentscheidungen lebendig bleiben: ADRs, Fitness Functions, Review-Rhythmen, Ausnahmeprozesse und messbare Architekturregeln.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Architecture Governance, Fitness Functions und ADR Betrieb als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Architecture Governance, Fitness Functions und ADR Betrieb - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class ArchitectureFitnessFunction { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# architecture-governance-fitness-functions-und-adr-betrieb.yaml owner : enterprise-architecture chapter : 77 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#78. Multi-Tenancy und Mandantenisolation

Mandantenfähigkeit in Java-Enterprise-Systemen: Tenant-Kontext, Datenisolation, Sicherheit, Migrationen, Observability und Betriebsrisiken.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Multi-Tenancy und Mandantenisolation als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Multi-Tenancy und Mandantenisolation - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class TenantContextPolicy { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# multi-tenancy-und-mandantenisolation.yaml owner : enterprise-architecture chapter : 78 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#79. Data Ownership und Integrationsgrenzen

Welche Daten gehören welchem System? Ownership, Kopien, Referenzen, Synchronisation, Reporting und Anti-Corruption-Layer werden sauber abgegrenzt.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Data Ownership und Integrationsgrenzen als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Data Ownership und Integrationsgrenzen - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class DataOwnershipRule { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# data-ownership-und-integrationsgrenzen.yaml owner : enterprise-architecture chapter : 79 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#80. Event-Versionierung, Schema Registry und Kompatibilität

Events müssen jahrelang lesbar bleiben: Versionierung, evolutionäre Schemas, Consumer-Kompatibilität, Replay und Deprecation.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Event-Versionierung, Schema Registry und Kompatibilität als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Event-Versionierung, Schema Registry und Kompatibilität - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class EventCompatibilityPolicy { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# event-versionierung-schema-registry-und-kompatibilitaet.yaml owner : enterprise-architecture chapter : 80 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#81. Kafka, JMS und Business-Idempotenz im Vergleich

Messaging ist nicht automatisch fachlich konsistent: Broker-Garantien, Transaktionen, Ordering, Duplicate Handling und fachliche Idempotenz im Vergleich.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Kafka, JMS und Business-Idempotenz im Vergleich als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Kafka, JMS und Business-Idempotenz im Vergleich - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class BrokerGuaranteeMatrix { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# kafka-jms-und-business-idempotenz-im-vergleich.yaml owner : enterprise-architecture chapter : 81 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#82. Transactional Messaging Lab: Outbox, Inbox und Dead Letter

Ein praxisnahes Lab für zuverlässige Nachrichtenverarbeitung mit Outbox, Inbox, Retry, DLQ, Reprocessing und Nachweisbarkeit.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Transactional Messaging Lab: Outbox, Inbox und Dead Letter als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Transactional Messaging Lab: Outbox, Inbox und Dead Letter - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class TransactionalMessagingLab { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# transactional-messaging-lab-outbox-inbox-und-dead-letter.yaml owner : enterprise-architecture chapter : 82 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#83. Workflow Engines und Prozessautomation in Java

Wann BPMN/Workflow-Engines helfen und wann ein einfacher Application Service besser ist: Camunda-, Temporal- und Orchestrator-Denken ohne Vendor-Lock-in.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Workflow Engines und Prozessautomation in Java als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Workflow Engines und Prozessautomation in Java - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class WorkflowDecision { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# workflow-engines-und-prozessautomation-in-java.yaml owner : enterprise-architecture chapter : 83 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#84. Search Architektur mit Elasticsearch und OpenSearch

Suchsysteme als Read Model: Indexing, Consistency, Reindexing, Mapping, Analyzer, Datenschutz und Betriebsgrenzen.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Search Architektur mit Elasticsearch und OpenSearch als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Search Architektur mit Elasticsearch und OpenSearch - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class SearchIndexingPolicy { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# search-architektur-mit-elasticsearch-und-opensearch.yaml owner : enterprise-architecture chapter : 84 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#85. Cache Invalidation, Konsistenz und Performance Trade-offs

Caching richtig einsetzen: TTL, Write-through, Cache-aside, Stampede-Schutz, Staleness und fachliche Konsequenzen.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Cache Invalidation, Konsistenz und Performance Trade-offs als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Cache Invalidation, Konsistenz und Performance Trade-offs - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class CacheDecisionPolicy { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# cache-invalidation-konsistenz-und-performance-trade-offs.yaml owner : enterprise-architecture chapter : 85 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#86. Distributed Locks, Leader Election und Job-Koordination

Wann verteilte Sperren nötig sind, warum sie gefährlich sein können und wie man Scheduler, Leader und Idempotenz kombiniert.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Distributed Locks, Leader Election und Job-Koordination als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Distributed Locks, Leader Election und Job-Koordination - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class LeaderElectionSketch { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# distributed-locks-leader-election-und-job-koordination.yaml owner : enterprise-architecture chapter : 86 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#87. API Lifecycle: Versioning, Deprecation und Consumer Management

APIs werden betrieben, nicht nur entwickelt: Versionen, Sunset, Consumer-Kommunikation, Breaking Changes und Compatibility Tests.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt API Lifecycle: Versioning, Deprecation und Consumer Management als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

API Lifecycle: Versioning, Deprecation und Consumer Management - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class ApiLifecyclePolicy { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# api-lifecycle-versioning-deprecation-und-consumer-management.yaml owner : enterprise-architecture chapter : 87 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#88. GraphQL im Enterprise-Java-Kontext

GraphQL als BFF-/Aggregationstechnik: Nutzen, Risiken, N+1-Probleme, Security, Caching und klare Grenzen zu Domain-APIs.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt GraphQL im Enterprise-Java-Kontext als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

GraphQL im Enterprise-Java-Kontext - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class GraphQlBoundaryPolicy { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# graphql-im-enterprise-java-kontext.yaml owner : enterprise-architecture chapter : 88 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#89. gRPC und Protobuf für interne Java Services

gRPC für interne Service-zu-Service-Kommunikation: Contracts, Streaming, Deadlines, Backward Compatibility und Observability.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt gRPC und Protobuf für interne Java Services als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

gRPC und Protobuf für interne Java Services - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class GrpcContractPolicy { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# grpc-und-protobuf-fuer-interne-java-services.yaml owner : enterprise-architecture chapter : 89 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#90. Bulk APIs, Datenimporte und Reprocessing

Große Datenmengen sauber verarbeiten: Import-Jobs, Validierung, Staging, Quarantäne, Wiederanlauf und fachlicher Abgleich.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Bulk APIs, Datenimporte und Reprocessing als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Bulk APIs, Datenimporte und Reprocessing - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class BulkImportPipeline { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# bulk-apis-datenimporte-und-reprocessing.yaml owner : enterprise-architecture chapter : 90 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#91. Performance Engineering mit JMH, Gatling und k6

Performance wird gemessen: Microbenchmarks, Lasttests, SLO-orientierte Szenarien, Kapazitätsgrenzen und Tuning-Schleifen.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Performance Engineering mit JMH, Gatling und k6 als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Performance Engineering mit JMH, Gatling und k6 - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class PerformanceExperiment { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# performance-engineering-mit-jmh-gatling-und-k6.yaml owner : enterprise-architecture chapter : 91 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#92. JVM GC Tuning: G1, ZGC und Shenandoah verstehen

Garbage Collection für Enterprise Java: Latenz, Durchsatz, Heap, Pausen, Monitoring und sichere Tuning-Strategien.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt JVM GC Tuning: G1, ZGC und Shenandoah verstehen als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

JVM GC Tuning: G1, ZGC und Shenandoah verstehen - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class GcTuningChecklist { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# jvm-gc-tuning-g1-zgc-und-shenandoah-verstehen.yaml owner : enterprise-architecture chapter : 92 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#93. Memory Leaks, Thread Dumps und Flame Graphs

Produktionsdiagnose für Java: Heap Dumps, Thread Dumps, Lock Contention, CPU-Profile, Flame Graphs und Runbook-Entscheidungen.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Memory Leaks, Thread Dumps und Flame Graphs als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Memory Leaks, Thread Dumps und Flame Graphs - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class DiagnosticTriage { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# memory-leaks-thread-dumps-und-flame-graphs.yaml owner : enterprise-architecture chapter : 93 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#94. Datenbank-Performance: Indizes, Query Plans und Locking

Datenbankperformance im Enterprise-Alltag: Indexstrategie, Query-Pläne, N+1, Locking, Partitionierung und ORM-Fallen.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Datenbank-Performance: Indizes, Query Plans und Locking als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Datenbank-Performance: Indizes, Query Plans und Locking - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class QueryPerformanceGuard { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# datenbank-performance-indizes-query-plans-und-locking.yaml owner : enterprise-architecture chapter : 94 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#95. Multi-Region, Disaster Recovery und Backup/Restore

Betrieb nach Ausfall denken: RPO, RTO, Replikation, Restore-Tests, DNS, Message Replay und Cutover-Pläne.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Multi-Region, Disaster Recovery und Backup/Restore als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Multi-Region, Disaster Recovery und Backup/Restore - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class DisasterRecoveryPlan { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# multi-region-disaster-recovery-und-backup-restore.yaml owner : enterprise-architecture chapter : 95 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#96. Blue/Green, Canary und Feature Flags

Release-Strategien mit kontrolliertem Risiko: Blue/Green, Canary, Dark Launch, Feature Flags und schnelle Rollbacks.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Blue/Green, Canary und Feature Flags als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Blue/Green, Canary und Feature Flags - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class ReleaseDecision { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# blue-green-canary-und-feature-flags.yaml owner : enterprise-architecture chapter : 96 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#97. Secrets, PKI und Zertifikatslebenszyklus

Secrets und Zertifikate professionell betreiben: Rotation, Trust Stores, mTLS, Expiry-Alerts und Umgebungsgrenzen.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Secrets, PKI und Zertifikatslebenszyklus als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Secrets, PKI und Zertifikatslebenszyklus - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class CertificateRotationPolicy { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# secrets-pki-und-zertifikatslebenszyklus.yaml owner : enterprise-architecture chapter : 97 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#98. Identity Architektur mit Keycloak und OIDC

Identity-Architektur für Enterprise Java: Realm, Clients, Scopes, Rollen, Token Relay, Service Accounts und Audit.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Identity Architektur mit Keycloak und OIDC als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Identity Architektur mit Keycloak und OIDC - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class IdentityAccessPolicy { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# identity-architektur-mit-keycloak-und-oidc.yaml owner : enterprise-architecture chapter : 98 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#99. OpenTelemetry Sampling, Traces, Metrics und Logs korrelieren

Observability als Entscheidungshilfe: Sampling, Trace-Kontext, Metriken, Logs, Exemplars und Kostenkontrolle.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt OpenTelemetry Sampling, Traces, Metrics und Logs korrelieren als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

OpenTelemetry Sampling, Traces, Metrics und Logs korrelieren - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class TelemetryCorrelation { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# opentelemetry-sampling-traces-metrics-und-logs-korrelieren.yaml owner : enterprise-architecture chapter : 99 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#100. FinOps und Kapazitätsplanung für Java Plattformen

Kosten und Leistung zusammen betrachten: Requests/Limits, JVM-Memory, Autoscaling, Lizenzkosten, Umgebungen und Rightsizing.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt FinOps und Kapazitätsplanung für Java Plattformen als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

FinOps und Kapazitätsplanung für Java Plattformen - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class CapacitySizingModel { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# finops-und-kapazitaetsplanung-fuer-java-plattformen.yaml owner : enterprise-architecture chapter : 100 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#101. Compliance, Audit Logging und Datenschutz-Nachweise

Technische Nachweise für regulierte Umgebungen: Audit Trails, Datenminimierung, Löschkonzepte, Zugriffsnachweise und Retention.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Compliance, Audit Logging und Datenschutz-Nachweise als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Compliance, Audit Logging und Datenschutz-Nachweise - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class AuditEvidenceModel { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# compliance-audit-logging-und-datenschutz-nachweise.yaml owner : enterprise-architecture chapter : 101 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#102. Open-Source-Lizenzen, GPL-Auswirkungen und Third-Party Notices

Lizenzrisiken verstehen: permissive Lizenzen, Copyleft, GPL/AGPL-Folgen, Notices, SBOM und Review-Prozess.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Open-Source-Lizenzen, GPL-Auswirkungen und Third-Party Notices als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Open-Source-Lizenzen, GPL-Auswirkungen und Third-Party Notices - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class LicenseReviewRule { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# open-source-lizenzen-gpl-auswirkungen-und-third-party-notices.yaml owner : enterprise-architecture chapter : 102 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#103. Upgrade-Wellen mit Renovate, Dependabot und Release Trains

Abhängigkeiten kontrolliert aktualisieren: Gruppierung, Testgates, Rollback, Kompatibilität und Verantwortlichkeiten.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Upgrade-Wellen mit Renovate, Dependabot und Release Trains als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Upgrade-Wellen mit Renovate, Dependabot und Release Trains - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class UpgradeWavePolicy { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# upgrade-wellen-mit-renovate-dependabot-und-release-trains.yaml owner : enterprise-architecture chapter : 103 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#104. Platform Engineering, IDP und Backstage-Denken

Interne Entwicklerplattformen: Golden Paths, Templates, Self-Service, Standards, Ownership und klare Produktverantwortung.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Platform Engineering, IDP und Backstage-Denken als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Platform Engineering, IDP und Backstage-Denken - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class GoldenPathTemplate { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# platform-engineering-idp-und-backstage-denken.yaml owner : enterprise-architecture chapter : 104 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#105. Contract-First APIs mit OpenAPI und AsyncAPI

Contracts zuerst denken: OpenAPI für REST, AsyncAPI für Events, Codegen, Contract Tests und Consumer-Kommunikation.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Contract-First APIs mit OpenAPI und AsyncAPI als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Contract-First APIs mit OpenAPI und AsyncAPI - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class ContractFirstPolicy { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# contract-first-apis-mit-openapi-und-asyncapi.yaml owner : enterprise-architecture chapter : 105 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#106. Code Generation, Mapping und Boilerplate Governance

Codegenerierung gezielt nutzen: MapStruct, OpenAPI-Generator, Annotation Processing, Generated Sources und Review-Regeln.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Code Generation, Mapping und Boilerplate Governance als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Code Generation, Mapping und Boilerplate Governance - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class CodeGenerationRule { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# code-generation-mapping-und-boilerplate-governance.yaml owner : enterprise-architecture chapter : 106 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#107. Maven Enforcer, Revapi und JApiCmp

Build-Governance im Maven-Projekt: Enforcer-Regeln, API-Break-Checks, Binary Compatibility und technische Schulden sichtbar machen.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Maven Enforcer, Revapi und JApiCmp als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Maven Enforcer, Revapi und JApiCmp - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class MavenQualityGate { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# maven-enforcer-revapi-und-japicmp.yaml owner : enterprise-architecture chapter : 107 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#108. ArchUnit Detailregeln für Enterprise Java

Architektur als Test: Schichten, Zyklen, Modulgrenzen, Namensregeln, Dependency Rules und Ausnahmedokumentation.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt ArchUnit Detailregeln für Enterprise Java als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

ArchUnit Detailregeln für Enterprise Java - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class ArchUnitRuleSet { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# archunit-detailregeln-fuer-enterprise-java.yaml owner : enterprise-architecture chapter : 108 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#109. Effective Java Regeln für Enterprise Projekte

Ausgewählte Effective-Java-Prinzipien im Enterprise-Kontext: Immutability, Builder, Exceptions, Generics, Concurrency und APIs.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Effective Java Regeln für Enterprise Projekte als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Effective Java Regeln für Enterprise Projekte - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class EffectiveJavaPolicy { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# effective-java-regeln-fuer-enterprise-projekte.yaml owner : enterprise-architecture chapter : 109 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz


#110. Capstone: Migration Factory und Architektur-Simulation

Abschlusskapitel: Wie man mehrere Legacy-Systeme systematisch bewertet, priorisiert, migriert und mit Architekturentscheidungen steuert.

#Warum dieses Thema in Version 5 wichtig ist

Version 5 behandelt Capstone: Migration Factory und Architektur-Simulation als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.

Capstone: Migration Factory und Architektur-Simulation - kompakte fachliche SVG-Darstellung

#Orientierungsrahmen

#Technisches Beispiel

Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.

text
package at.aydinsude.enterprise.v5.sketch ; import java.time.Instant ; import java.util.List ; import java.util.Map ; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class MigrationFactorySimulation { public ArchitectureDecision evaluate ( ArchitectureContext context ) { int risk = context . businessCriticality () + context . integrationCount () + context . operationalComplexity (); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard" ; return new ArchitectureDecision ( action , risk , Instant . now (), List . of ( "document trade-offs" , "add automated evidence" , "define rollback or recovery path" )); } public record ArchitectureContext ( int businessCriticality , int integrationCount , int operationalComplexity , Map < String , String > tags ) {} public record ArchitectureDecision ( String action , int riskScore , Instant decidedAt , List < String > evidence ) {} }

Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.

text
# capstone-migration-factory-und-architektur-simulation.yaml owner : enterprise-architecture chapter : 110 risk_level : senior evidence_required : - adr - architecture-test - runbook - monitoring-dashboard review : cadence : quarterly escalation : architecture-board

#Typische Fehlerbilder

#Prüffragen für Senior Entwickler

#Merksatz

#V6 Erweiterung - Praxislabor, Capstone und Prüfung

#111. V6 Praxislabor: Lernpfad vom Lesen zum Umsetzen

V6 macht aus dem Lehrbuch ein Trainingssystem mit Labs, Lösungen, Prüfchecklisten und Capstone-Projekt.

#112. Lab 01: Maven Multi-Module sauber schneiden

Ein Lab für Parent-POM, Module, Dependency-Richtung, Enforcer-Regeln und Architekturgrenzen.

#113. Lab 02: Domain Model, Aggregate und Invarianten

Bestellung, Positionen, Zahlung und Reservierung als fachliches Modell mit klaren Invarianten.

#114. Lab 03: REST API mit Fehlervertrag und OpenAPI

REST-Endpunkte, Problem Details, Validation, Versionierung und Consumer-Vertrag im Praxisbeispiel.

#115. Lab 04: JPA, Transaktionen und Repository Pattern

JPA-Entities, Transaction Boundary, Repository-Port, Lazy Loading und N+1-Risiken verstehen.

#116. Lab 05: SOAP-Legacy-Adapter kapseln

Alte SOAP-Clients werden hinter einem Port/Adapter isoliert, damit Domain und Use Cases sauber bleiben.

#117. Lab 06: Event-driven Outbox mit Reprocessing

Domain Events, Outbox, Publisher, Retry, DLQ und fachliche Idempotenz als Übungsaufgabe.

#118. Lab 07: Security mit OAuth2/OIDC und Rollenmodell

JWT Claims, Rollen, Scopes, Token Relay und fachliche Berechtigungen im Enterprise-Kontext.

#119. Lab 08: Observability mit Logs, Metrics und Traces

Korrelation, Trace-ID, Business-Metriken, SLO und Runbook-Verknüpfung praktisch einbauen.

#120. Lab 09: Testing mit Unit, Contract und Testcontainers

Testpyramide, Architekturtests, Contract Tests und Integrationstests mit Datenbank-/Broker-Simulation.

#121. Lab 10: OpenShift Deployment und Config

Container, ConfigMaps, Secrets, Health Checks, Ressourcenlimits, Routes und Rollout-Strategie.

#122. Lab 11: Performance, Diagnostik und Lasttests

JMH, k6/Gatling-Denken, Thread Dumps, Heap Dumps und Query-Analyse als kontrollierte Diagnose.

#123. Lab 12: Final Capstone Migration

Ein End-to-End-Lab: Legacy verstehen, modernisieren, absichern, testen, deployen und dokumentieren.

#124. Refactoring Workshop: Monster Service zerlegen

Ein großer Vorher/Nachher-Workshop für Service-Monster, Transaktionsmischung, Mapping-Chaos und harte Infrastrukturkopplung.

#125. Refactoring Workshop: JDBC-Spaghetti zu Repository

Legacy-JDBC, SQL-Streuung und Ressourcenfehler werden Schritt für Schritt zu Ports und Repositories umgebaut.

#126. Refactoring Workshop: EJB zu Application Service

EJB-Session-Bean-Logik wird in Use Cases, Ports und klare Transaktionsgrenzen überführt.

#127. Refactoring Workshop: JSP/JSF zu REST und BFF

UI-nahe Logik, Session State und HTML-Formularfluss werden in API, BFF und Frontend-Verträge getrennt.

#128. Entscheidungsbaum: Spring Boot, Jakarta EE, Quarkus oder Micronaut

Ein fachlicher Entscheidungsbaum für Team-Skills, Runtime, Cloud-Native, Standardisierung und Betriebsmodell.

#129. Entscheidungsbaum: REST, SOAP, Messaging, GraphQL oder gRPC

Integration wird bewusst gewählt: Consumer, Latenz, Kopplung, Vertrag, Streaming und Governance bestimmen die Wahl.

#130. Entscheidungsbaum: Monolith modularisieren oder Microservices schneiden

Teamgrenzen, Datenhoheit, Releasefähigkeit und Betriebskosten entscheiden über den Schnitt.

#131. Interviewtraining: Senior Java Enterprise Fragen

Fragen und Musterantworten zu Architektur, Transaktionen, Messaging, Security, JPA, Maven und Betrieb.

#132. Codeanalyse-Training: schlechte Beispiele erkennen

Code-Smells, Transaktionsfehler, Exception-Probleme, N+1, fehlende Idempotenz und harte Kopplung erkennen.

#133. Prüfung: Multiple Choice und offene Architekturfragen

Ein prüfungsähnlicher Teil mit MC-Fragen, offenen Fragen, Lösungslogik und Bewertungsraster.

#134. Produktionsreife Checkliste: API und Fehlerbehandlung

Eine kompakte Checkliste für APIs, Fehlerverträge, Validierung, Rate Limits, Security und Observability.

#135. Produktionsreife Checkliste: Datenbankmigration

Flyway/Liquibase-Denken, Rollback, Backfill, Zero-Downtime, Locks, Indizes und Datenqualität.

#136. Produktionsreife Checkliste: Security und Compliance

OIDC, Secrets, Audit, SBOM, Lizenzprüfung, Datenschutz und minimale Rechte als Produktionsstandard.

#137. Produktionsreife Checkliste: Observability und Incident

SLO, Dashboards, Alerts, Runbooks, Incident-Timeline und Postmortem als Lernschleife.

#138. Produktionsreife Checkliste: CI/CD und Release

Build, Test, SBOM, Container Scan, Deployment Gates, Rollback und Freigabeprozess.

#139. Capstone Architekturakte: ADRs, Runbooks und Nachweise

Die finale Architekturakte bündelt Entscheidungen, Risiken, Verträge, Tests, Diagramme und Betriebsnachweise.

#140. V6 Abschluss: Lernpfad, Wiederholung und nächste Stufe

Abschluss mit Wiederholungsplan, Selbsttest, Projektcheck und möglichen nächsten Vertiefungen.

⌂ Cockpit