Maven oder Gradle: welches Build-Werkzeug euer Java-Projekt tatsächlich braucht
Die Entscheidung fällt nicht am Dateiformat, sondern an drei Fragen: Wie oft baut ihr, wie viele Module hängen zusammen, und wie viel Sonderfall steckt in eurem Ablauf.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Gewechselt wird aus Geschmack, gemerkt wird es beim nächsten Wechsel im Team
Der Anlass für die Diskussion ist selten eine Messung. Meistens ist es ein neues Teammitglied, das Gradle aus dem letzten Projekt kennt, oder eine Anleitung im Netz, deren Beispiel in Kotlin geschrieben ist. Der Umbau ist dann schnell gemacht, und die ersten Wochen fühlen sich gut an. Die Rechnung kommt später: Wenn die Person, die den Build geschrieben hat, das Haus verlässt, steht ein Skript da, das niemand mehr in Gänze versteht, und die Fehlersuche darin dauert länger als die Fehlersuche im Anwendungscode.
Der umgekehrte Fehler ist genauso teuer, fällt aber langsamer auf. Ein Team bleibt bei Maven, weil es immer so war, obwohl der Build zwanzig Module umfasst und ein vollständiger Durchlauf auf dem Build-Server eine Viertelstunde braucht. Diese Viertelstunde wirkt bei jeder Änderung, bei jedem Pull Request und bei jedem Versuch, einen Fehler nachzustellen. Über ein Jahr gerechnet ist das keine Kleinigkeit, sondern ein Posten, der sich in Kalenderzeit ausdrücken lässt.
Beide Fehler haben dieselbe Ursache: Die Entscheidung wird ohne die Zahlen getroffen, die sie beantworten würden. Wie lange dauert ein vollständiger Durchlauf heute, wie lange ein Durchlauf nach einer kleinen Änderung, wie oft läuft der Build pro Tag, und wie viel davon ist Arbeit, die schon einmal gemacht wurde? Diese vier Werte stehen in eurem CI-Server, sie müssen nur ausgelesen werden.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Die Kriterien, an denen sich der Alltag unterscheidet
Verglichen werden hier nicht Sprachmittel und Dateiformate, sondern die sechs Eigenschaften, die im Projektalltag Zeit kosten oder sparen: Lesbarkeit für Neue, Geschwindigkeit bei wiederholten Läufen, Beweglichkeit bei Sonderfällen, Nachvollziehbarkeit der Abhängigkeitsversionen, Aufwand für ein gewöhnliches Java-Projekt und der Stand der Werkzeugkette.
Maven
fester Ablauf aus vorgegebenen Phasen, Beschreibung in XML, aktuell 3.9.16 als allgemein verfügbare Fassung, Maven 4 noch im Release-Kandidaten-Stadium
Gradle
Aufgabengraph statt fester Phasen, Beschreibung in Kotlin oder Groovy, aktuell 9.7.0, mit Zwischenspeichern für Aufgaben und Konfiguration
| Entscheidungsfrage | Maven | Gradle |
|---|---|---|
| Wie schnell versteht jemand Neues ein fremdes Projekt? | Stärke Der Ablauf ist überall derselbe, das Verzeichnisschema ebenfalls, und die Datei beschreibt, was gebaut wird, nicht wie. Wer schon einmal ein Maven-Projekt gesehen hat, findet sich in jedem anderen sofort zurecht. | Kommt darauf an Ein schlanker Build mit den Standard-Plugins liest sich gut. Sobald eigene Aufgaben, Konventions-Plugins und Logik dazukommen, ist die Build-Beschreibung Anwendungscode und wird auch so gelesen, also mit dem entsprechenden Zeitaufwand. |
| Wie schnell läuft ein Durchlauf, wenn sich wenig geändert hat? | Kommt darauf an Jede Phase läuft, ob sie muss oder nicht. Parallelität gibt es über Module, und mit dem Maven Daemon lässt sich der Start beschleunigen. Der große Hebel, Arbeit ganz zu überspringen, fehlt aber im Kern. | Stärke Aufgaben werden übersprungen, wenn sich ihre Eingaben nicht geändert haben. Dazu kommen ein Build-Cache, der auch über Rechner hinweg funktioniert, und ein Configuration Cache, der den Aufbau des Aufgabengraphen einspart. |
| Wie leicht baust du einen Schritt ein, den kein Standard-Plugin abdeckt? | Kommt darauf an Möglich ist es über ein eigenes Plugin oder über die Einbindung eines Skripts. Beides funktioniert, fühlt sich aber wie ein Umweg an, weil der Ablauf aus festen Phasen besteht und jeder Sonderschritt an eine davon gehängt werden muss. | Stärke Eine Aufgabe mit Eingaben, Ausgaben und Abhängigkeiten zu anderen Aufgaben ist der vorgesehene Fall und keine Ausnahme. Deklarierte Ein- und Ausgaben sind dabei nicht Kür: Erst sie erlauben es dem Werkzeug, die Aufgabe beim nächsten Mal zu überspringen. |
| Wie leicht siehst du, warum eine bestimmte Bibliotheksversion im Build landet? | Kommt darauf an Maven nimmt die nächstliegende Festlegung im Abhängigkeitsbaum, also die Version, deren Pfad zu eurem Projekt am kürzesten ist. Bei gleicher Tiefe gewinnt die zuerst deklarierte. Das ist nachvollziehbar, hängt aber an Reihenfolge und Tiefe und überrascht deshalb regelmäßig. | Stärke Gradle betrachtet alle angeforderten Versionen im Graphen und wählt standardmäßig die höchste. Das ist unabhängig von Reihenfolge und Tiefe, und mit Constraints lässt sich eine Version verbindlich festlegen, ohne dass jemand eine Abhängigkeit von Hand nach oben ziehen muss. |
| Wie viel Aufwand kostet ein gewöhnliches Java-Projekt ohne Sonderwünsche? | Stärke Fast keinen. Verzeichnisschema, Phasen und Ausgabeform sind vorgegeben, die Datei enthält im Wesentlichen Abhängigkeiten und ein paar Versionsangaben. Über die Struktur wird nicht diskutiert, weil es nichts zu entscheiden gibt. | Kommt darauf an Mit den Standard-Plugins ist ein Java-Projekt ebenfalls in wenigen Zeilen beschrieben. Der Unterschied liegt darin, dass es Entscheidungen gibt, wo Maven keine anbietet, und dass Teams diese Entscheidungen dann auch treffen, meistens unterschiedlich. |
| Wie ist der Stand der Werkzeugkette gegenüber neuen Java-Versionen? | Kommt darauf an Die 3.9er-Reihe wird gepflegt und läuft mit aktuellen Java-Versionen. Maven 4 bringt mit der Trennung von Build-POM und Consumer-POM eine seit Langem gewünschte Änderung, steht aber mit 4.0.0-rc-6 noch vor der Freigabe. Für Projekte heißt das: warten oder bewusst auf einen Kandidaten setzen. | Stärke Gradle veröffentlicht regelmäßig und nennt in der Kompatibilitätsmatrix für jede Java-Version die früheste passende Fassung. Die aktuelle 9er-Reihe unterstützt Java bis Version 26. Der Preis dafür sind eigene Versionssprünge, die im Projekt Anpassungen verlangen. |
Wie schnell versteht jemand Neues ein fremdes Projekt?
Der Ablauf ist überall derselbe, das Verzeichnisschema ebenfalls, und die Datei beschreibt, was gebaut wird, nicht wie. Wer schon einmal ein Maven-Projekt gesehen hat, findet sich in jedem anderen sofort zurecht.
Ein schlanker Build mit den Standard-Plugins liest sich gut. Sobald eigene Aufgaben, Konventions-Plugins und Logik dazukommen, ist die Build-Beschreibung Anwendungscode und wird auch so gelesen, also mit dem entsprechenden Zeitaufwand.
Wie schnell läuft ein Durchlauf, wenn sich wenig geändert hat?
Jede Phase läuft, ob sie muss oder nicht. Parallelität gibt es über Module, und mit dem Maven Daemon lässt sich der Start beschleunigen. Der große Hebel, Arbeit ganz zu überspringen, fehlt aber im Kern.
Aufgaben werden übersprungen, wenn sich ihre Eingaben nicht geändert haben. Dazu kommen ein Build-Cache, der auch über Rechner hinweg funktioniert, und ein Configuration Cache, der den Aufbau des Aufgabengraphen einspart.
Wie leicht baust du einen Schritt ein, den kein Standard-Plugin abdeckt?
Möglich ist es über ein eigenes Plugin oder über die Einbindung eines Skripts. Beides funktioniert, fühlt sich aber wie ein Umweg an, weil der Ablauf aus festen Phasen besteht und jeder Sonderschritt an eine davon gehängt werden muss.
Eine Aufgabe mit Eingaben, Ausgaben und Abhängigkeiten zu anderen Aufgaben ist der vorgesehene Fall und keine Ausnahme. Deklarierte Ein- und Ausgaben sind dabei nicht Kür: Erst sie erlauben es dem Werkzeug, die Aufgabe beim nächsten Mal zu überspringen.
Wie leicht siehst du, warum eine bestimmte Bibliotheksversion im Build landet?
Maven nimmt die nächstliegende Festlegung im Abhängigkeitsbaum, also die Version, deren Pfad zu eurem Projekt am kürzesten ist. Bei gleicher Tiefe gewinnt die zuerst deklarierte. Das ist nachvollziehbar, hängt aber an Reihenfolge und Tiefe und überrascht deshalb regelmäßig.
Gradle betrachtet alle angeforderten Versionen im Graphen und wählt standardmäßig die höchste. Das ist unabhängig von Reihenfolge und Tiefe, und mit Constraints lässt sich eine Version verbindlich festlegen, ohne dass jemand eine Abhängigkeit von Hand nach oben ziehen muss.
Wie viel Aufwand kostet ein gewöhnliches Java-Projekt ohne Sonderwünsche?
Fast keinen. Verzeichnisschema, Phasen und Ausgabeform sind vorgegeben, die Datei enthält im Wesentlichen Abhängigkeiten und ein paar Versionsangaben. Über die Struktur wird nicht diskutiert, weil es nichts zu entscheiden gibt.
Mit den Standard-Plugins ist ein Java-Projekt ebenfalls in wenigen Zeilen beschrieben. Der Unterschied liegt darin, dass es Entscheidungen gibt, wo Maven keine anbietet, und dass Teams diese Entscheidungen dann auch treffen, meistens unterschiedlich.
Wie ist der Stand der Werkzeugkette gegenüber neuen Java-Versionen?
Die 3.9er-Reihe wird gepflegt und läuft mit aktuellen Java-Versionen. Maven 4 bringt mit der Trennung von Build-POM und Consumer-POM eine seit Langem gewünschte Änderung, steht aber mit 4.0.0-rc-6 noch vor der Freigabe. Für Projekte heißt das: warten oder bewusst auf einen Kandidaten setzen.
Gradle veröffentlicht regelmäßig und nennt in der Kompatibilitätsmatrix für jede Java-Version die früheste passende Fassung. Die aktuelle 9er-Reihe unterstützt Java bis Version 26. Der Preis dafür sind eigene Versionssprünge, die im Projekt Anpassungen verlangen.
Was passt wann
- Wenn es ein gewöhnliches Java-Projekt mit wenigen Modulen ist und der Build heute niemanden stört
- bleib bei Maven und steck die Zeit in Tests statt in eine Migration ohne Gegenwert.
- Wenn ein Durchlauf nach einer kleinen Änderung mehrere Minuten braucht und viele Module zusammenhängen
- rechnet Gradle durch, denn genau dort liegt der Vorteil, und er ist messbar.
- Wenn außer Java noch Kotlin, Android oder ein Frontend-Build im Projekt liegen
- nimm Gradle, das ist an dieser Stelle keine Abwägung mehr.
- Wenn der Wunsch nach dem Wechsel von einer Person kommt und niemand sonst das Werkzeug kann
- schulst du erst das Team und entscheidest danach, sonst entsteht ein Build mit genau einem Zuständigen.
Vier Werte, und das Werkzeug steht fest
- 01 Wie lange dauert ein Durchlauf nach einer Änderung in einer einzigen Klasse?
- 02 Wie viele Module hängen wirklich voneinander ab, und wie tief ist der Graph?
- 03 Wie viele Sonderschritte enthält euer Ablauf, die kein Standard-Plugin abdeckt?
- 04 Liegt außer Java noch etwas im Projekt, etwa Kotlin, Android oder ein Frontend?
- 05 Wer im Team kann den Build nach einem Wechsel noch ändern?
Woran du die Entscheidung tatsächlich festmachst
Sechs Punkte reichen aus, und für keinen davon braucht ihr eine Testmigration. Vier lest ihr aus dem CI-Server aus, zwei aus dem Projekt selbst.
Die Bauzeit trennen nach vollständig und nach Änderung
Miss zwei Werte getrennt: den vollständigen Durchlauf aus einem leeren Arbeitsverzeichnis und den Durchlauf nach einer Änderung in einer einzigen Klasse. Der erste Wert lässt sich mit keinem Werkzeug wesentlich drücken. Der zweite ist genau der, an dem Gradle seinen Vorteil ausspielt, weil es Aufgaben überspringt, deren Eingaben sich nicht geändert haben.
Zählen, wie viele Module tatsächlich voneinander abhängen
Bei einem Projekt aus zwei oder drei Modulen ist die Frage nach paralleler Ausführung und Zwischenspeicherung wenig wert. Ab etwa einem Dutzend Module mit echten Abhängigkeiten untereinander wird sie zur wichtigsten. Zeichnet den Abhängigkeitsgraphen einmal auf, das ist eine halbe Stunde Arbeit und beantwortet die Frage meistens allein.
Den Sonderbedarf im Ablauf ehrlich aufschreiben
Erzeugter Code, Prüfungen gegen fremde Systeme, mehrere Auslieferungsvarianten aus derselben Quelle, Signaturen, Container-Images: All das lässt sich in Maven über Plugins abbilden, aber es fühlt sich an, als würde man gegen das Werkzeug arbeiten. In Gradle ist es eine Aufgabe mit Eingaben und Ausgaben und damit der vorgesehene Fall. Wenn eure Liste hier lang ist, ist die Frage bereits beantwortet.
Prüfen, ob mehr als Java im Spiel ist
Sobald Kotlin, Android, C++ oder ein Frontend-Build mit im Projekt liegen, ist Gradle die naheliegende Wahl, weil es dafür gepflegte Unterstützung mitbringt. Bei einem reinen Java-Projekt ohne diese Nachbarn fällt dieser Punkt weg und mit ihm ein großer Teil der Begründung für den Wechsel.
Den Stand der Werkzeuge gegen eure Java-Version halten
Gradle veröffentlicht eine Kompatibilitätsmatrix: Java 17 ab Gradle 7.3, Java 21 ab 8.5, Java 25 ab 9.1.0, Java 26 ab 9.4.0. Bei Maven ist 3.9.16 die aktuelle allgemein verfügbare Fassung, Maven 4 steht mit 4.0.0-rc-6 noch vor der Freigabe und verlangt Java 17. Wer eine neue Java-Version einführen will, prüft diese Zeile zuerst.
Die Frage nach der Nachfolge stellen
Wie viele Leute im Haus können den Build heute lesen und ändern, und wie viele könnten es nach einem Wechsel? Ein Maven-Projekt versteht praktisch jede Java-Person nach fünf Minuten. Ein Gradle-Build mit eigenen Aufgaben und Konventions-Plugins ist Anwendungscode und braucht jemanden, der ihn pflegt. Das ist kein Argument dagegen, aber es ist eine Stelle im Fahrplan.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Fester Ablauf gegen Aufgabengraph
Maven beschreibt ein Projekt und überlässt den Ablauf dem Werkzeug. Es gibt einen festen Lebenszyklus aus Phasen, und Plugins hängen sich an diese Phasen. Wer mvn package aufruft, weiß, was passiert, ohne die Datei gelesen zu haben: übersetzen, Tests laufen lassen, Artefakt bauen. Diese Vorhersagbarkeit ist der eigentliche Wert. Sie bedeutet auch, dass eine Datei aus einem fremden Projekt keine Überraschungen enthält, weil sie gar keinen Platz dafür hat.
Gradle beschreibt Aufgaben und ihre Abhängigkeiten untereinander. Daraus entsteht ein Graph, den das Werkzeug vor jedem Lauf aufbaut und dann abarbeitet. Der Vorteil liegt darin, dass jede Aufgabe ihre Eingaben und Ausgaben kennt und deshalb übersprungen werden kann, wenn sich nichts geändert hat. Der Nachteil liegt darin, dass die Beschreibung dieses Graphen in einer echten Programmiersprache erfolgt, und alles, was in einer Programmiersprache geschrieben ist, kann kompliziert werden.
Diese beiden Bauweisen erklären die meisten Unterschiede im Alltag. Wenn jemand fragt, warum ein Maven-Build eine Aufgabe wiederholt, die schon erledigt ist, lautet die Antwort: weil die Phase durchläuft. Wenn jemand fragt, warum ein Gradle-Build sich anders verhält als erwartet, lautet die Antwort meistens: weil in der Konfigurationsphase Logik steht, die dort niemand vermutet hätte. Beides sind Eigenschaften und keine Fehler.
Warum Gradle-Builds schneller sind und wann nicht
Der Geschwindigkeitsvorteil hat drei Quellen, und keine davon wirkt beim ersten Lauf. Die erste ist die inkrementelle Ausführung: Eine Aufgabe, deren Eingaben unverändert sind, wird übersprungen. Die zweite ist der Zwischenspeicher für Bauartefakte, der auch Ergebnisse von anderen Rechnern wiederverwenden kann, was im CI-Server und bei mehreren Branches viel bringt. Die dritte ist der Zwischenspeicher für die Konfiguration, der den Aufbau des Aufgabengraphen einspart und damit die Zeit, die vor der eigentlichen Arbeit vergeht.
Alle drei setzen voraus, dass der Build sich an die Regeln hält. Aufgaben müssen ihre Eingaben und Ausgaben vollständig deklarieren, sonst überspringt das Werkzeug etwas, das es nicht hätte überspringen dürfen, oder es baut ständig neu, obwohl nichts passiert ist. Ein Build, der in der Konfigurationsphase Dateien liest, Umgebungsvariablen abfragt oder Zufallswerte erzeugt, kann den Konfigurationsspeicher nicht nutzen. Das ist die häufigste Ursache dafür, dass ein Gradle-Projekt langsam bleibt, obwohl alle Schalter gesetzt sind.
Auf der Maven-Seite gibt es Gegenmittel, sie greifen nur nicht so weit. Module lassen sich parallel bauen, und der Maven Daemon hält einen Prozess am Leben und spart damit die Startzeit der virtuellen Maschine. Was fehlt, ist die Fähigkeit, einzelne Arbeitsschritte anhand ihrer Eingaben zu überspringen. Für ein kleines bis mittleres Projekt fällt das nicht ins Gewicht. Für ein Projekt mit zwanzig Modulen und einem Testbestand, der Minuten braucht, fällt es täglich ins Gewicht.
Abhängigkeitsversionen: nächstliegende Festlegung gegen höchste Version
Hier liegt der Unterschied, der im Alltag die meisten Überraschungen erzeugt, und er ist in beiden Dokumentationen sauber beschrieben. Maven wählt bei mehreren angeforderten Versionen derselben Bibliothek die nächstliegende Festlegung, also die Version, deren Pfad zu eurem Projekt im Abhängigkeitsbaum am kürzesten ist. Liegen zwei Kandidaten gleich tief, gewinnt die zuerst deklarierte. Das lässt sich immer erklären, aber es hängt an der Struktur des Baums und an der Reihenfolge der Einträge, und beides ändert sich, ohne dass jemand es beabsichtigt.
Gradle betrachtet stattdessen alle angeforderten Versionen im Graphen und wählt standardmäßig die höchste davon. Das ist unabhängig von Tiefe und Reihenfolge und deshalb leichter vorherzusagen. Es bringt eine andere Eigenschaft mit: Eine Abhängigkeit weit unten im Baum kann eine Bibliothek nach oben ziehen, ohne dass es in eurer Datei sichtbar wäre. Deshalb gibt es Constraints, mit denen ihr eine Version verbindlich festlegt, egal wer sie anfordert.
Praktisch heißt das für beide Werkzeuge dasselbe: Verlasst euch nicht auf die Vermittlung, sondern legt die Versionen fest, die euch wichtig sind. In Maven ist das der Abschnitt dependencyManagement, oft über ein importiertes BOM. In Gradle sind es Plattformen und Version Catalogs, mit denen sich Versionen an einer Stelle für alle Module bündeln lassen. Beides ist wenig Arbeit und erspart die Diskussion darüber, warum im CI-Server eine andere Version landet als auf dem Rechner nebenan.
Was ein Wechsel kostet und wann er sich rechnet
Ein Wechsel ist kein Übersetzungsvorgang, sondern eine Neuformulierung. Die Abhängigkeiten und die Verzeichnisstruktur lassen sich weitgehend übernehmen, denn Gradle kennt dasselbe Schema. Was neu entsteht, ist alles, was in eurem bisherigen Build über Plugins geregelt war: Erzeugung von Code, Signaturen, Container-Images, Veröffentlichung, Prüfwerkzeuge. Für die verbreiteten Fälle gibt es Entsprechungen, für die eigenen schreibt ihr Aufgaben. Rechne mit einem Vielfachen dessen, was die reine Umstellung der Abhängigkeiten kostet.
Dazu kommt ein Punkt, den Teams regelmäßig unterschätzen: Ein Wechsel ist nur dann fertig, wenn niemand mehr das alte Werkzeug braucht. Ein Zwischenzustand mit zwei parallelen Builds ist der teuerste aller Zustände, weil jede Änderung an zwei Stellen gemacht und an zwei Stellen geprüft werden muss. Wenn ihr wechselt, dann in einem Zug und mit einem Termin, an dem die alten Dateien gelöscht werden.
Rechnen tut sich der Wechsel dort, wo die Zahlen es hergeben: bei vielen Modulen, langen Durchlaufzeiten und einem Ablauf, der über das Übliche hinausgeht. Er rechnet sich nicht, weil ein Werkzeug moderner klingt, weil die Beispiele im Netz häufiger in der einen Sprache geschrieben sind oder weil eine Person es besser kennt. Diese Gründe sind nachvollziehbar, aber sie tragen die Kosten nicht, und sie halten der Frage nicht stand, wer den Build in drei Jahren pflegt.
Dazu passende Kurse
Wenn der Build im Team nur noch von einer Person verstanden wird, sind Java-Seminare rund um Build und Abhängigkeiten der schnellste Weg, diesen Engpass aufzulösen.
Soll der Build am Ende auch ausliefern und nicht nur übersetzen, findest du bei cmt Kurse zum Zusammenspiel von Build und Auslieferung .
Wie sicher bist du beim Thema wirklich?
Lesen fühlt sich schnell nach Können an. Ein kurzer Test zeigt dir, was davon schon sitzt und wo sich ein Kurs lohnt. Kostenlos, ohne Anmeldung, mit einer Erklärung zu jeder Antwort.
Wo du genau das übst
Sehr umfangreicher Überblick über Zusammenhänge und Anwendungsbereiche. Sehr zu empfehlen.
Effektives, gemeinsames Erarbeiten der Aufgaben mit vielen praktischen Tipps.
Sehr guter Trainer und gute Aufbereitung der Inhalte und auch eingehen auf Fragen der Beteiligten.
Häufige Fragen
Ist Gradle grundsätzlich schneller als Maven?
Sollen wir auf Maven 4 warten?
Können wir Maven und Gradle im selben Haus nebeneinander betreiben?
Warum landet auf dem CI-Server eine andere Bibliotheksversion als bei uns lokal?
Brauchen wir für Gradle unbedingt Kotlin?
Deine Ansprechpartner
Du bist dir nicht sicher, welcher Kurs oder welches Level zu dir passt? Wir beraten dich persönlich und kostenlos.
Yves Hoppe
Weiterbildung & Beratung
Hilft dir, aus dem Programmierung-Programm den passenden Kurs für deinen Stand zu finden.
Norbert Jansen
Beratung & Inhouse
Plant mit dir Inhouse-Trainings, die auf eure Abläufe und euren Datenbestand zugeschnitten sind.
Den eigenen Build einmal von innen ansehen
Bei cmt gehst du im Kurs zum jeweiligen Build-Werkzeug den kompletten Ablauf durch, von den Abhängigkeiten bis zur Auslieferung, und siehst dabei, welche Zeit im Durchlauf wo verloren geht.
Passt dazu
- Java 17, 21 oder 25: welche LTS-Version euer Projekt tragen sollte
- Von Java 8 wegkommen: was der Sprung auf eine aktuelle LTS wirklich verlangt
- Spring Boot oder Quarkus: was Startzeit und Speicher im Betrieb kosten
- Wann sich Testautomatisierung rechnet und wann sie Geld verbrennt