Während die erste Welle der KI-Adoption in vielen Organisationen auf Cloud-APIs setzte, ist dieser Ansatz in sicherheitskritischen und regulierten Umgebungen häufig nicht nutzbar. Vertraulichkeitsanforderungen, Datenschutzvorgaben und der Bedarf an technisch durchsetzbaren Betriebsgrenzen stehen dem entgegen. In On-Premises-Setups erweitert sich die Architektur um zusätzliche Laufzeitkomponenten, etwa LLM-Serving, Retrieval und Wissensartefakte wie Indizes und Prompts. Der Fokus verschiebt sich damit von der reinen Modellnutzung zur Plattformfrage: Wie lassen sich Datenzugriffe und Berechtigungen entlang der Pipeline kontrollieren? Wie bleiben Änderungen an Modellen, Prompts und Indizes nachvollziehbar? Und wie lassen sich Fehlerfälle reproduzierbar eingrenzen und zurückrollen?
An dieser Stelle wird die Wahl der Runtime relevant. Viele der geforderten Eigenschaften lassen sich nicht nachträglich ergänzen, sondern müssen durch Laufzeitmechanismen und Betriebsmodelle unterstützt werden. Java 26 enthält hierfür Bausteine, die sich in regulierten Umgebungen kontrolliert einsetzen lassen. Structured Concurrency (Preview) für die Orchestrierung paralleler Schritte, die Vector API (Incubator) für effizientere CPU-Pfade und AOT-Cache-Verbesserungen für kürzeres Kaltstart- und Warm-up-Verhalten. Entscheidend ist nicht die unbedingte Nutzung einzelner Sprach- oder Runtime-Features, sondern deren Einbettung in klare Betriebsgrenzen. Die betroffenen Pfade werden gekapselt betrieben, Versionen gepinnt, Änderungen durchlaufen definierte CI/CD-Gates. So lassen sich Effizienzpotenziale nutzen, ohne Stabilität und Nachvollziehbarkeit des Gesamtsystems zu gefährden.
Governance vor Feature-Nutzung: Stabilität, Support und Blast Radius
In sicherheitskritischen Umgebungen zählt nicht nur, ob ein Feature verfügbar ist, sondern welchen Stabilitäts- und Lifecycle-Status es hat. Preview- und Incubator-APIs sind bewusst veränderlich. Sie werden deshalb nicht breit in der Codebase verwendet, sondern als kalkulierte Optimierung mit klaren Betriebsgrenzen eingesetzt – gekapselt in dedizierten Komponenten, mit definierter Rückfalloption und abgesichert über messbare Release-Gates wie Performance- und Sicherheitsmetriken. Deterministisch erzwingbar sind dabei vor allem die Kontrollen außerhalb des Modells. Guardrails auf Modell-Ebene bleiben häufig heuristisch. Ihre Wirksamkeit muss daher regressionsfest gemessen und im Release-Prozess geprüft werden. Im Folgenden wird dieses Vorgehen als „Preview/Incubator-Governance“ referenziert: Kapselung, Fallback, gepinnte Versionen und messbare Release-Gates.
On-Premises-RAG in Kubernetes
Der Betrieb von Large Language Models (LLMs) innerhalb der eigenen Infrastruktur wird häufig gewählt, um Datenabflussrisiken zu minimieren und volle Kontrolle über die Verarbeitungskette zu behalten. Ein bewährtes Muster für solche Szenarien ist Retrieval-Augmented Generation (RAG), bei dem das generische Wissen eines LLMs zur Laufzeit durch interne Unternehmensdaten angereichert wird.
Der Request-Flow: Ein RAG-Service in Aktion
Um die technischen Anforderungen zu verstehen, folgen wir einem einzelnen User-Request durch eine typische Kubernetes-basierte On-Premises-Architektur:
- Ingress & Auth: Der Request trifft ein und wird authentifiziert.
- Retrieval (Fan-Out): Der Service sucht parallel in verschiedenen Vektor-Indizes (z. B. “Wikis”, “Tickets”) nach relevanten Kontexten.
- Reranking: Die gefundenen Schnipsel werden neu sortiert, dedupliziert und auf ein Kontextbudget reduziert, um die Relevanz für das LLM zu maximieren.
- Generation: Der angereicherte Prompt wird an das lokal gehostete Modell gesendet und die Antwort generiert.
- Guardrails: Die Antwort wird vor der Auslieferung auf Richtlinien-/Berechtigungsverstöße und sensible Inhalte geprüft und ggf. redigiert.

Jeder dieser Schritte kostet Zeit und Ressourcen. In Cloud-Umgebungen skaliert man oft einfach die Hardware. On-Premises, wo Hardware-Beschaffungszyklen lang sind, wird die Effizienz der Laufzeitumgebung – hier der JVM – zum entscheidenden Faktor.
Warum „Performance“ bei On-Premises meist mit GPU-Auslastung beginnt
Wie gut die GPUs ausgelastet sind, entscheidet oft über die Kosten – nicht nur durch echtes Idle, sondern vor allem durch Padding-Overhead: Die GPU rechnet dann zwar, aber ein Teil der Rechenzeit geht in „Leertakte“, weil kürzere Sequenzen im Batch künstlich aufgefüllt werden. Gleichzeitig entsteht Leerlauf häufig nicht durch „zu wenig Rechenleistung“, sondern weil LLM-Inferenz in der Praxis oft durch Speicherbandbreite begrenzt ist – besonders in der Decode-Phase, wenn Gewichte und KV-Cache ständig nachgeladen werden müssen. Deshalb lohnt sich vor jeder Detailoptimierung ein kurzer Realitätscheck: Liegt der Engpass im Modell-Serving (Scheduling/Batching/Cache) oder in den CPU-getriebenen Teilen der Pipeline (Retrieval, Reranking, Guardrails)? Erst wenn das klar ist, ist auch klar, ob JVM-Optimierungen der größte Hebel sind – oder ob Serving-Mechanismen wie effizienteres Batching und KV-Cache-Management zuerst kommen sollten.
Isolation durch das Sidecar-Pattern
Ein etabliertes Sicherheits- und Betriebs-Pattern ist die Dezentralisierung des Vektor-Stores. Statt einen riesigen, zentralen Vektor-Datenbank-Cluster zu betreiben, auf den alle Apps zugreifen, werden Vektor-Indizes als read-only-Artefakte behandelt.
Ein Java-Service kann hierfür einen kompakten Vektor-Index direkt als Sidecar-Container oder als read-only gemountetes Persistent Volume einbinden. Das stärkt die Isolation auf Deployment-Ebene: Ein Service für HR-Daten bekommt nur den HR-Index ausgeliefert und kann Engineering-Daten gar nicht erst „sehen“. In Kombination mit Kubernetes-RBAC, Namespaces, NetworkPolicies und getrennten Build-/Deploy-Pipelines entsteht so eine robuste Trennlinie zwischen Daten-Domänen.
Damit diese Isolation auditierbar bleibt, ist insbesondere die Artefakt-Governance des Index relevant. Indizes werden signiert, versioniert und mit Provenienz (Quelle, Erstellzeitpunkt, Pipeline-Run) versehen. Rollouts erfolgen nachvollziehbar über Umgebungen und Freigaben. Ein schlanker „Break-Glass“-Mechanismus (z. B. Feature-Toggle/Traffic-Routing) ermöglicht bei Sicherheitsvorfällen oder fehlerhaften Inhalten das schnelle Zurückschalten auf eine vorherige Index-Version. Damit wird Sidecar-Isolation nicht nur zu einem Architektur-Pattern, sondern zu einem prüfbaren Kontrollmechanismus.
Die Isolation über ein Sidecar (signierter, read-only Index) erhöht Domänentrennung und Auditierbarkeit, ist aber nicht kostenlos: Große Indizes treiben Storage-, Netzwerk- und Rollout-Zeiten (Warm-up/Cache) nach oben. Bei sehr großen Korpora oder hoher Änderungsrate kann ein zentraler Vektorstore mit strikter Mandantenisolation und sauberem Versioning operativ günstiger sein.
Java 26: Bausteine für effiziente KI-Backends
Mit Java 26 konsolidiert das OpenJDK-Projekt mehrere Initiativen, die für solche KI-Workloads relevant sind. Die Kombination aus Verbesserungen bei Startzeit (Project Leyden), Vektorisierung (Project Panama) und Nebenläufigkeit (Project Loom) adressiert spezifische Engpässe in RAG-Pipelines.
Project Leyden: Optimierter Startup durch AOT-Caching (JEP 516)
Java 26 erweitert die AOT-Fähigkeiten mit JEP 516 (Ahead-of-Time Object Caching with Any GC). Die Idee dahinter ist, wiederkehrende Initialisierungszustände Ahead-of-Time vorzubereiten und beim nächsten Start wiederzuverwenden. Java 26 erweitert dies mit JEP 516 insbesondere um GC-unabhängiges Object Caching, als Baustein innerhalb des Leyden/AOT-Cache-Pfads. Das reduziert die „Cold Start“-Kosten, ohne den Betriebsmodus einer klassischen JVM aufzugeben.
In der Praxis wird die Anwendung in einer CI/CD-Pipeline in einem kontrollierten Trainingslauf gestartet, der typische Initialisierungspfade durchläuft (Tokenizer laden, Konfiguration parsen, Model-/Index-Metadaten vorbereiten). Die dabei entstehenden, wiederverwendbaren Zustände werden in einem Cache-Archiv abgelegt. Beim späteren Pod-Start kann die JVM diese vorbereiteten Teile nutzen, sodass der Service schneller „Ready“ wird und Warm-up-Phasen kürzer ausfallen – abhängig von Workload, Garbage Collector und der konkreten Initialisierungslogik.
Gerade bei Lastspitzen, wenn neue Pods hochfahren, zählt jede Sekunde bis zur ersten erfolgreichen Antwort. AOT-Caching hilft, schwere Startpfade aus dem kritischen Pfad zu nehmen (z. B. Initialisierung von Tokenizern, Modell-Wrappern oder Parsern) und macht Skalierungsvorgänge im Betrieb planbarer.
Die Vector API (JEP 529) im Umfeld der Panama-Initiativen
KI-Inferenz und Ähnlichkeitssuche basieren auf linearer Algebra, spezifisch auf Vektoroperationen. On-Premises steht nicht immer für jeden Service eine GPU zur Verfügung. Hier wird die CPU zur Rechenzentrale. Die Vector API (in Java 26 im 11. Incubator-Stadium) ermöglicht es, SIMD-Instruktionen (Single Instruction, Multiple Data) moderner CPUs (AVX-512, NEON) explizit zu nutzen. Dies ist besonders relevant für das “Reranking” oder die Berechnung von Cosine-Similarity im eigenen Service.
Da die Vector API in Java 26 im Incubator-Stadium ist, erfolgt ihr Einsatz in sicherheitskritischen Umgebungen bewusst als kalkulierte Optimierung nach der oben beschriebenen Preview/Incubator-Governance. Vektorisierte Pfade werden als austauschbare Beschleuniger gekapselt (z. B. Sidecar-/Worker-Service), mit stabilem API-Vertrag und einem konfigurierbaren Fallback auf skalare Implementierung bzw. alternative Libraries.
Code-Beispiel: Optimiertes Skalarprodukt
Hier wird deutlich, wie die API parallele Lanes der CPU nutzt, um Berechnungen zu beschleunigen – essenziell für latenzkritische Retrieval-Schritte auf der CPU.
import jdk.incubator.vector.*;
// Berechnet das Skalarprodukt (Dot Product) zweier Float-Vektoren (z. B. Embeddings).
// Hinweis: Beispiel ist bewusst kompakt; Fehlerbehandlung/Null-Checks weggelassen.
static float vectorDotProduct(float[] a, float[] b) {
int len = Math.min(a.length, b.length);
var species = FloatVector.SPECIES_PREFERRED;
var sum = FloatVector.zero(species);
int i = 0;
// Hauptschleife: Verarbeite SIMD-Blöcke
int upper = species.loopBound(len);
for (; i < upper; i += species.length()) {
var va = FloatVector.fromArray(species, a, i);
var vb = FloatVector.fromArray(species, b, i);
sum = sum.add(va.mul(vb));
}
// Reduktion der Vektor-Lanes auf einen skalaren Wert
float result = sum.reduceLanes(VectorOperators.ADD);
// Tail: verbleibende Elemente
for (; i < len; i++) {
result += a[i] * b[i];
}
return result;
}
Project Loom: Structured Concurrency (JEP 525)
Der oben beschriebene “Fan-Out” im Retrieval-Schritt (parallele Suche in Wiki, Jira, Code-Repo) ist anfällig für Fehler. Wenn eine Datenquelle hängt, soll das nicht die gesamte Request blockieren.
Structured Concurrency erlaubt es, parallele Retrieval-Tasks als Scope mit klaren Abbruch- und Timeout-Regeln zu modellieren. So lässt sich der Ressourcenverbrauch deterministisch begrenzen. Da Structured Concurrency ein Preview-Feature ist, wird es gemäß der Preview/Incubator-Governance über plattformnahe Abstraktionen eingeführt. Dadurch lassen sich Timeouts zentral konfigurieren und Cancellation-Propagation sowie Ressourcenbegrenzungen einheitlich umsetzen. Zusätzlich wird das Laufzeitverhalten über Tracing/Metriken überprüfbar gemacht (z. B. Abbruchgründe, Timeout-Quoten, offene Tasks pro Request), um die gewünschte Wirkung – kontrolliertes Fan-Out ohne Hänger – operativ nachweisen zu können. So erhöht die Scope-Modellierung die Resilienz gegenüber Teilausfällen, ohne eine unprüfbare Stabilitätszusage an einen Preview-Status zu knüpfen.
Code-Beispiel: RAG-Orchestrierung
Anstatt mit komplexen CompletableFutures zu hantieren, definiert der Code den Scope und die Abbruchbedingungen deklarativ.
// Orchestrierung von Retrieval und PII-Check
try (var scope = StructuredTaskScope.open()) {
var retrievalTask = scope.fork(() -> vectorStore.search(query));
var piiCheckTask = scope.fork(() -> piiFilter.check(query));
scope.join(); // wartet auf beide; bei Fehler wird abgebrochen
scope.throwIfFailed(); // propagiert ersten Fehler
if (Boolean.TRUE.equals(piiCheckTask.get())) {
return generateAnswer(retrievalTask.get());
}
}
return null; // oder definierter Fallback
Der Vorteil im Betrieb: Hängende Subtasks werden deutlich seltener, weil der Scope beim Verlassen (Erfolg, Fehler oder Timeout) sicherstellt, dass alle Subtasks sauber beendet werden.
DevOps-Patterns für die LLM-Ära
Die Einführung von LLMs verändert die DevOps-Praxis spürbar: Code ist nicht mehr das einzige Artefakt, das versioniert, getestet und kontrolliert ausgerollt werden muss – Prompts und Modelle rücken in den Fokus.
GitOps für Prompts (“Prompts as Code”)
Prompts sind in LLM-Systemen Verhaltenslogik: Schon kleine Änderungen am System-Prompt können Antwortqualität, Formatverhalten und die Wirksamkeit von Sicherheitsregeln deutlich verändern. Deshalb sollten Prompts nicht als dynamischer Content in Datenbanken versteckt, sondern wie Code behandelt werden – versioniert, reviewbar und reproduzierbar auslieferbar. In der Praxis bedeutet das, dass Prompts im Git gepflegt werden und die Applikation eine konkrete Prompt-Version (z. B. v1.2) referenziert. So ist jede Änderung nachvollziehbar, und ein Rollback der Applikation setzt automatisch auch den Prompt auf den zuletzt getesteten Stand zurück, ohne manuelle Eingriffe oder Konfigurationsdrift zwischen Umgebungen zu verursachen.
Automated Semantic Testing (Evals)
Unit-Tests reichen bei nicht-deterministischen LLMs nicht aus. In CI/CD-Pipelines etablieren sich daher semantische Evaluationen (“Evals”).
Dabei bewertet oft ein stärkeres “Lehrer-Modell” die Antworten der Anwendung anhand eines “Golden Sets” (Frage-Antwort-Paare). Nur wenn Metriken wie “Faktentreue” oder “Relevanz” stabil bleiben, wird das Deployment freigegeben. Tools für diese Evaluation lassen sich mittlerweile gut in JUnit-Workflows integrieren.
Um semantische Evaluationen auditfähig zu betreiben, sollten Evals als Regression-Kontrolle mit definierten Akzeptanzkriterien verstanden werden: Neben Qualitätsmetriken (Relevanz/Faktentreue) werden Sicherheitsmetriken (PII-Leakage-Rate, Prompt-Injection-Erfolgsrate, Policy-Violations) als Gates etabliert. Golden Sets werden versioniert und um adversariale Testfälle erweitert; außerdem wird die Varianz nicht-deterministischer Modelle berücksichtigt (z. B. Mehrfachläufe und Schwellenwerte). Damit entsteht ein reproduzierbarer Nachweis, dass Änderungen an Prompt, Retrieval-Konfiguration oder Modell nicht unbemerkt die Sicherheits- und Compliance-Eigenschaften verschlechtern.
Sicherheit & Governance: Die 5 Kontrollpunkte
In regulierten und sicherheitskritischen Umgebungen sollte Sicherheit, soweit möglich, deterministisch erzwungen werden – man kann sich nicht darauf verlassen, dass ein LLM „nett“ reagiert.
Guardrails, die auf Modellen oder Klassifikatoren beruhen (Injection-Erkennung, Halluzinations-Heuristiken), sind Signalgeber – Policy-Enforcement muss aber über deterministische Kontrollen wie Identity/ABAC, Tool-Allowlisting, Egress-Control und Audit-Logging erfolgen.
Orientiert an den typischen Risikomustern (etwa den OWASP-Empfehlungen für LLM-Anwendungen) haben sich fünf Stellen bewährt, an denen sich Governance und Sicherheit besonders wirksam verankern lassen.
- Access & Identity
Noch bevor überhaupt Retrieval oder ein Modellaufruf passiert, muss geklärt sein, wer welche Informationen sehen darf. In RAG-Systemen wird das häufig über Identitätskontext (User, Rolle, Mandant) und Metadatenfilter im Retrieval gelöst – so wird der Suchraum von Beginn an auf freigegebene Dokumente begrenzt. - Input Guardrails
Alles, was in Richtung Modell geht, sollte vorab geprüft werden: sensible Inhalte (PII) werden maskiert oder entfernt, und typische Prompt-Injection-Muster werden erkannt, bevor sie Anweisungen im Prompt oder Tooling missbrauchen können. Das Ziel ist nicht „Perfektion“, sondern ein definierter Mindeststandard, der Angriffe und Datenabfluss messbar reduziert. - Retrieval Guardrails
Der dritte Kontrollpunkt sitzt im Retrieval selbst. Hier entscheidet sich, welche Dokumente tatsächlich im Kontext landen. Wichtig ist, dass nur freigegebene Quellen einfließen und die Daten-Provenienz nachvollziehbar bleibt: Welche Quelle wurde warum gezogen, ist sie aktuell, passt sie zur Identität des Nutzers, und ist sie überhaupt für diesen Use Case freigegeben? - Output Guardrails
Auch wenn Input und Retrieval sauber sind, kann ein Modell Inhalte falsch kombinieren oder fehlinterpretieren. Deshalb muss auch die Antwort validiert werden – etwa durch strukturierte Ausgaberegeln (Schema/JSON), durch Plausibilitätschecks und, wo passend, durch einen Halluzinations-Check, der prüft, ob Kernaussagen durch die bereitgestellten Quellen gedeckt sind. - Audit & Observability
Der fünfte Kontrollpunkt ist in der Praxis oft der entscheidende. Für forensische Analysen und Nachvollziehbarkeit muss die Entscheidungskette lückenlos sein: Welcher Nutzer-Input führte zu welchen Retrieval-Treffern, welcher Kontext wurde ans Modell gegeben, welche Antwort kam zurück und welche Guardrail-Entscheidungen wurden unterwegs getroffen? Ohne dieses Tracing lässt sich weder zuverlässig debuggen noch sauber nachweisen, dass ein System innerhalb der Policies betrieben wurde.
Implementierungsstrategien: Kriterien für die Framework-Wahl
Bei der Umsetzung solcher Plattformen in Java stehen Architekten oft vor der Wahl des passenden Frameworks. Statt Tool-Namen gegeneinander auszuspielen, lohnt der Blick auf zwei unterschiedliche Implementierungs-Philosophien: eine, die auf maximale Integrationsfähigkeit im Enterprise-Umfeld optimiert, und eine, die Laufzeit- und Ressourceneffizienz im Cloud-Native-Betrieb priorisiert.
A) Der Enterprise-Integrator (z. B. Spring AI)
Dieser Ansatz spielt seine Stärken aus, wenn GenAI-Funktionalität in bestehende Anwendungen und Plattformstandards „eingewoben“ werden soll. Im Vordergrund steht weniger minimale Laufzeit, sondern die reibungsarme Integration in etablierte Bausteine wie Security, Datenzugriff, Konfiguration und Monitoring. Für Teams, die KI-Funktionen in Brownfield-Systeme bringen („Add AI to the Monolith“ oder „Add AI to existing Services“), ist das oft der pragmatischste Weg, weil zentrale Querschnittsthemen bereits konsistent gelöst sind und sich neue GenAI-Komponenten in vorhandene Governance- und Betriebsprozesse einordnen lassen. Die höhere Abstraktion kann zudem den Einstieg beschleunigen, weil typische Integrationsfragen (Auth, Observability, Konfiguration) nicht jedes Mal neu verdrahtet werden müssen.
B) Der Cloud-Native Performer (z. B. Quarkus mit LangChain4j)
Dieser Ansatz ist stärker auf Effizienz fokussiert: schneller Startup, kleiner Footprint und eine Ausrichtung auf hochskalierende oder kurzlebige Workloads. Das ist besonders attraktiv, wenn GenAI-Funktionen als schlanke, spezialisierte Microservices betrieben werden sollen – etwa als Reranking-Service, Guardrail-Worker oder Retrieval-Komponente, die unabhängig skaliert und aktualisiert wird. In solchen Setups zählen Ressourcenverbrauch pro Pod und Startverhalten unter Last häufig mehr als maximale Framework-Integrationstiefe. Zusätzlich kann die Option, Native Images zu verwenden, in bestimmten Betriebsmodellen (z. B. viele Instanzen, aggressive Skalierung) ein Vorteil sein, weil Startzeiten und Speicherbedarf planbarer werden.
In der Praxis ist die Framework-Wahl daher selten eine „besser/schlechter“-Entscheidung, sondern eine Gewichtung: Steht die tiefe Anbindung an ein bestehendes Enterprise-Ökosystem im Vordergrund, ist der Integrator-Ansatz oft der schnellere Weg in die Produktion. Geht es um maximale Ressourceneffizienz und sehr schnelles Skalieren spezialisierter Komponenten in Kubernetes, spricht mehr für den Performer-Ansatz. Beide Richtungen lassen sich mit modernen Java-Features kombinieren. Entscheidend ist, welche Betriebsziele (Integrationsaufwand vs. Laufzeiteigenschaften) dominieren.
Souveränität durch Technologie
Java 26 positioniert sich als leistungsfähige Plattform für KI-Workloads im Backend. Die Neuerungen adressieren drei Kernanforderungen moderner RAG-Architekturen. Erstens liefert die Vector API die Grundlage für effiziente CPU-Berechnungen. Zweitens verkürzt AOT-Caching über Project Leyden die Kaltstartzeiten. Drittens ermöglicht Structured Concurrency eine kontrollierte, resiliente Parallelisierung.
Der Weg zur eigenen, souveränen LLM-Plattform muss nicht ausschließlich über experimentelle Python-Services führen. Mit robusten DevOps-Patterns und durchgängigen Guardrails lässt sich die Leistungsfähigkeit moderner Java-Runtimes sicher nutzbar machen. Innovation entsteht durch gezielte Performance-Bausteine. Compliance wird durch Architektur-Kapselung, nachvollziehbare Freigabepfade und lückenloses Audit-Tracing abgesichert. So lässt sich eine On-Premises-LLM-Plattform betreiben, die effizient arbeitet und zugleich prüfbar innerhalb definierter Richtlinien funktioniert.
Drei Leitsätze für regulierte On-Premises-LLM-Plattformen
- Governance vor Feature-Nutzung. Preview- und Incubator-APIs sind kalkulierte Optimierungen – gekapselt in dedizierten Komponenten, mit definierter Rückfalloption und abgesichert über messbare Release-Gates.
- Determinismus außerhalb des Modells. Policy-Enforcement wird über Identity/ABAC, Tool-Allowlisting, Egress-Control und Audit-Logging erzwungen. Modell basierte Guardrails bleiben Signalgeber und müssen regressionsfest gemessen werden.
- Artefakte sind Deployment-Objekte. Prompts, Indizes und Golden Sets werden versioniert, signiert und über reproduzierbare CI/CD-Freigabepfade ausgerollt – inklusive Rollback, ohne Konfigurationsdrift zwischen Umgebungen.
Weiterführende Referenzen
- OpenJDK JEP 516: Ahead-of-Time Object Caching with Any GC
- OpenJDK JEP 525: Structured Concurrency (Preview)
- OpenJDK JEP 529: Vector API (Incubator)
- OpenJDK Project-Seiten: Leyden, Loom, Panama
- OWASP: Top 10 for Large Language Model Applications