Für ein internes Werkzeug mit REST-API sollte die Auslieferung als kleines, schnell startendes natives Binary erfolgen.
Als Framework standen Spring Boot und Micronaut zur Auswahl, im Team gab es vor allem Spring-Erfahrung.
Statt nach Bauchgefühl zu entscheiden, haben wir beide Kandidaten mit identischen Prototypen als GraalVM Native Image gebaut und vermessen.
Die Messwerte und die Erkenntnisse aus dem Vergleich stellen wir in diesem Beitrag vor.
Geschrieben von Thomas Kruse am 28. September 2026
Bei der Anmeldung per sogenanntem Magic Link erhält der Benutzer einen Link, über den er sich ohne Passwort anmeldet.
Der Link wird typischerweise per E-Mail zugestellt, der erforderliche Zugriff auf das Postfach tritt damit an die Stelle der Eingabe eines Passworts.
Spring Security bringt in neueren Versionen für dieses Verfahren mit dem One-Time-Token-Login eine fertige Unterstützung von Haus aus mit mit.
In diesem Beitrag wird die Umsetzung mit dem aktuellen Spring Boot 4 und Spring Security 7 gezeigt.
Dabei betrachten wir zwei Fälle:
Links, die genau einmal genutzt werden können, so wie es typischerweise auch genutzt wird und auch von Spring direkt vorgesehen ist.
Als Alternative wird eine Konfiguration für Links, die über einen längeren Zeitraum oder sogar dauerhaft funktionieren, vorgestellt.
Für den zweiten Fall gehen wir auf die damit verbundenen Risiken, sinnvolle Einsatzszenarien und generelle Alternativen ein.
Eine lauffähige Beispielanwendung steht am Ende des Artikels zum Download bereit.
Im Beitrag Kubernetes Ops Hilfe mit lokalem LLM hat ein handgeschriebener OpenAI-kompatibler Proxy kubectl als Tool für ein lokales Sprachmodell verfügbar gemacht.
Dabei wurde Open WebUI als Chat-Oberfläche genutzt, so dass eine interaktive Diagnose möglich wurde.
llama.cpp bringt inzwischen zwei Dinge von Haus aus mit, die einen alternativen Aufbau möglich machen:
Eine eigene, in llama-server eingebettete Chat-Oberfläche und einen MCP-Client, der Werkzeuge über das Model Context Protocol (MCP) anspricht.
Dieser Beitrag zeigt, wie sich kubectl so über einen minimalen, selbst geschriebenen MCP-Server anbinden lässt, bewusst ohne auf ein fertiges MCP-Projekt zurückzugreifen, um die Prinzipien von MCP sichtbar zu machen.
Im Ordner sample liegt dazu ein vollständiges, lauffähiges Docker-Compose-Setup.
Für den produktiven Einsatz verweist der Beitrag am Ende auf etablierte Alternativen.
Bei der Neuinstallation eines Manjaro Linux Systems mit verschlüsselter Systempartition bestimmen zwei Eigenschaften der beteiligten Werkzeuge vor, wie die Installation mit modernem LUKS2 umgesetzt werden kann.
Calamares, der grafische Installer von Manjaro, legt bei aktivierter Verschlüsselung lediglich einen Container im alten LUKS1 Format an.
Der Bootloader GRUB kann dazu einen LUKS2 Container mit den heute üblichen Parametern nicht aufschließen.
Aus beidem folgt ein Ablauf, der von der Standardinstallation von Manjaro abweicht und effektiv auf ein Design herausläuft, wie es auch beispielsweise Ubuntu umsetzt:
/boot liegt unverschlüsselt auf einer eigenen Partition und bringt eine Ramdisk mit, die alles notwendige zur Unterstützung von LUKS2 beinhaltet.
Dazu werden Partitionierung, LUKS2 Container und Dateisysteme einmalig von Hand vorbereitet, bevor der grafische Installer die eigentliche Installation übernimmt.
GraalVM Native Image übersetzt Java-Anwendungen vorab in ein natives Binary.
Der Start dauert dann Millisekunden statt Sekunden, der Speicherbedarf sinkt deutlich, und zur Laufzeit wird keine JVM mehr benötigt.
Für Anwendungen, die auf jedem Knoten eines Kubernetes-Clusters mitlaufen, sind das gute Argumente.
Im konkreten Beispielprojekt, in dem sich ein schwer zu findender Fehler eingeschlichen hatte, ging es genau um Kubernetes Infrastruktur:
Ein eigener CSI-Treiber wird als DaemonSet betrieben und belegt so Ressourcen auf jeder einzelnen Node.
Damit diese Optimierungen funktionieren, verschiebt Native Image Arbeit vom Programmstart in den Build.
Dazu gehört die Klasseninitialisierung:
Statische Initializer werden nicht zwangsläufig beim Start ausgeführt, sondern können bereits beim Bau des Binaries laufen.
Deren Ergebnis wandert als fertiges Objektnetz in den sogenannten Image Heap.
Keine Initialisierung mehr zur Laufzeit, keine Arbeit für einen Just in Time Compiler.
Das ist zum einen der Hebel für den Geschwindigkeitsgewinn aber gleichzeitig eine Fehlerquelle, die in der klassischen JVM-Welt so nicht existiert.
Was ein statischer Initializer ableitet und ermittelt, wird einmalig zum Buildzeitpunt auf der Buildmaschine ausgeführt.
Die NullPointerException ist nach wie vor einer der häufigsten Laufzeitfehler in Java-Anwendungen.
Das eigentliche Problem ist selten der einzelne vergessene Check, sondern dass an keiner Stelle festgehalten ist, welche Werte überhaupt null sein dürfen und welche nicht.
Diese Information steckt bestenfalls im Kopf der Entwickler oder in der Dokumentation, aber nicht im Typsystem.
JSpecify ist ein herstellerübergreifender Satz von Annotationen, der genau diese Information ausdrückt.
Mit Spring Framework 7 und Spring Boot 4 ist das gesamte Spring-API mit diesen Annotationen versehen.
Damit die Annotationen nicht nur Dokumentation bleiben, braucht es ein Werkzeug, das sie prüft.
Im Maven-Build übernimmt das Error Prone zusammen mit dem NullAway-Plugin von Uber.
In Kubernetes-Clustern wird viel operatives Wissen zur Nutzung der richtigen kubectl-Befehle benötigt.
Diese muss man neben den relevanten Kubernetes Grundlagen erst kennen:
Welches Argument filtert Pods im CrashLoopBackOff, wie ließt man Events zu einem Deployment aus, welcher Selector gehört zu welchem Service.
Ein lokal betriebenes Sprachmodell kann die Übersetzung von Fragen zum Kubernetes Cluster übernehmen:
Aus einer Frage in natürlicher Sprache werden passende kubectl-Aufrufe, deren Ausgabe das Modell anschließend zusammenfasst.
Als Beispiel dient dazu ein vollständiges Docker-Compose-Setup aus llama.cpp, einem schlanken Python-Proxy und Open WebUI als Chat-Oberfläche.
Dieser Beitrag stellt Konzept und Architektur des Setups vor, zeigt den Nutzen an einem konkreten Beispiel und geht auf Alternativen zu diesem Ansatz ein: Im Kleinen wie in der grundsätzlichen Architektur.
Wer Claude, Codex und Co. bei der Entwicklung von Spring-Anwendungen einsetzt, musste vielleicht auch schon feststellen, dass gerade neue Features des Frameworks nicht optimal verwendet werden.
Aufgrund fehlender oder veralteter Trainingsdaten erzeugen die Sprachmodelle zwar korrekten, aber nicht optimalen Code.
Sie definieren Beans, obwohl diese mittlerweile aus einer Autoconfiguration kommen, nutzen veraltete Klassen (z. B. JdbcTemplate statt JdbcClient) oder entpacken munter JARs, um den aktuellen Quellcode von Spring zu lesen.
In diesem Beitrag zeige ich, wie man mit Spring AI einen Model-Context-Protocol-Server (MCP-Server) für LLMs bereitstellt, der hier Abhilfe schafft.
Der Server gibt Agents Zugriff auf die Spring-Dokumentation, die für das aktuelle Projekt relevant ist.
Im Beitrag Talos Kubernetes auf Hetzner Cloud einfach einrichten wurde ein Kubernetes Cluster mit Talos Linux auf einem Hetzner Cloud Server eingerichtet.
Die dort erzeugte Netzwerkkonfiguration deckte bishher lediglich das klassische IPv4 ab.
Inzwischen sind IPv4 Adressen ein knappes Gut, so dass diese auch zunehmend teurer werden.
Hetzner stellt jedem Cloud Server zusätzlich ein /64 IPv6-Subnetz bereit, das ohne Aufpreis genutzt werden kann.
Dieser Beitrag erweitert das Vorgehen und somit auch das Script, das den Netzwerk-Patch erzeugt, um IPv6.
Anschließend werden die wesentlichen Unterschiede beschrieben, die beim Betrieb von Talos und Kubernetes im Dual-Stack, also mit IPv4 und IPv6 parallel, zu beachten sind.
Wer Container Images aus einer Registry bezieht, verlässt sich darauf, dass Inhalt und Herkunft stimmen.
Signaturen machen das prüfbar: Sie binden einen Image-Digest an einen Aussteller und schützen so vor Manipulation zwischen Push und Pull.
Im OSS-Umfeld ist dafür meist Cosign aus dem Sigstore-Projekt im Einsatz, das wir in einem eigenen Beitrag behandelt haben.
Cosign ist aber nicht das einzige praxisrelevante Werkzeug.
Dieser Beitrag stellt die zweite verbreitete Option vor: Notation aus dem Notary Project.