Quarkus – leichtgewichtiges JEE mit Spaß!

Von Dirk Weil, GEDOPLAN IT Training.

Java-Anwendungen sind zumeist serverbasiert. Als Standard bietet Jakarta EE die notwendigen Zutaten wie Persistenz, Komponenteninjektion, Transaktionen, Webservices etc. an. Der als J2EE auf die Welt gekommene Standard blickt mittlerweile auf 22 Jahre Entwicklung mit Höhen und Tiefen zurück. Kritiker behaupten standhaft, JEE sei zu schwergewichtig und für neue Anwendungen nicht geeignet. Mit Quarkus liegt der Gegenbeweis auf dem Tisch – oder in der Entwicklungsumgebung!

Die ursprüngliche Idee von J2EE war sicher, dass Application Server wie WebLogic oder WebSphere betrieben werden und jeweils mehrere JEE-Anwendungen beherbergen – wie eine Art Betriebssystem für Java-Server-Anwendungen. Organisatorisch und aus Gründen der Isolation der Anwendungen untereinander finden wir aber eher 1-zu-1-Beziehungen: Eine Anwendung läuft auf einem Server, der meist sogar auf einem dedizierten (virtuellen) Rechner betrieben wird. In Zeiten der Aufspaltung von Monolithen zu Modulithen (modularisierte Monolithen) oder Microservices ist eine Inflation der Serverinstallationen die Folge (Abb. 1).

Es stellt sich somit die Frage, ob die separaten Server nötig sind oder ob man sie nicht in die Anwendungen integrieren kann. Diese Idee ist nicht neu: Spring Boot, Dropwizard, Micronaut u. a. m. implementieren dieses Modell. Und nun auch Quarkus. Brauchen wir noch ein weiteres Framework? Was ist das Besondere an Quarkus?

JEE und MicroProfile – oder der Wert von Standards

JEE hat eine bewegte Geschichte: 1998 als J2EE veröffentlicht, wurde der Standard 2006 in Java EE umgetauft. In den Jahren 2016 und 2017 war nicht klar, ob Oracle als Rechteinhaber überhaupt noch Interesse an Java EE hatte – Befürchtungen wurden laut, dass Java EE „eingestampft“ würde. 2017 übertrug Oracle das Projekt an die Eclipse Foundation, wo der Standard unter dem Namen Jakarta EE als Open Source weiterentwickelt wird. Die neuerliche Umbenennung war notwendig, weil Oracle die Rechte am Namen Java EE behalten hat – für viele in der Community ein unverständliches Verhalten.

Aller Kritik zum Trotz stellt JEE einen großen Vorteil dar: Kompatibilität. Anwendungen können nahezu unverändert auf verschiedenen Serverprodukten betrieben werden. Soll’s ein kostengünstiger Open-Source-Server sein oder lieber ein „großes“ Produkt mit Support? Kein Problem: Der Kunde/das Team hat die Wahl – und auch ein späterer Wechsel ist möglich. Zudem hat es in den 22 Jahren J2EE/Java EE/Jakarta EE kaum Breaking Changes gegeben. Ältere Anwendungen können somit meist ohne größere Änderungen auch auf aktuellen Servern (mit aktuellen JVMs und aktuellen Security Patches) weiter betrieben werden.

Diese Abwärtskompatibilität ist nicht leicht zu erhalten und stellt sicher einen der Gründe dafür dar, dass die Releasezyklen von 3-4 Jahren recht groß waren und sich der Standard für viele zu langsam weiterentwickelte. Hier kommt MicroProfile ins Spiel – ebenfalls ein Open-Source-Projekt der Eclipse Foundation. MicroProfile optimiert Enterprise Java nach eigener Aussage für Microservice-Architekturen. Es ergänzt JEE um diverse Bausteine, die für verteilte Architekturen – insbesondere in der Cloud – nötig sind (Abb. 2).

Die Kombination von JEE und MP erscheint recht sinnvoll: Während der „Tanker“ JEE zuverlässig im Standard-Fahrwasser – nun mit Releases ungefähr im Jahresabstand –  vorankommt, setzt MP „Schnellboote“ ins Wasser und unterstützt mit Minor Releases alle paar Monate aktuelle Bedarfe in den Bereichen Microservices, Cloud und Serverless.

Bemerkenswert ist, dass alle aktuellen JEE-Produkte auch MP unterstützen: u. a. WildFly, Payara, Open Liberty – und auch Quarkus.

Supersonic Subatomic Java

Quarkus ist nicht gerade bescheiden in der Beschreibung auf quarkus.io (Abb. 3): Überschallgeschwindigkeit, winzige Größe und Java – wir werden im Folgenden sehen, wie das zusammenpasst. Quarkus kommt wie WildFly aus dem Hause Red Hat.
Das Open-Source-Projekt ist in gewisser Weise der Nachfolger von Thorntail, dessen Weiterentwicklung mit Ablauf des Jahres 2020 endet. Quarkus ist optimiert für extrem kurze Startzeiten und läuft sowohl auf einer klassischen JVM wie auch nativ mit Hilfe der GraalVM.

Dabei ist Quarkus sowohl Framework als auch Toolset: Der Project Setup erfolgt mit Hilfe eines Maven-Plugins (Gradle geht auch). Dabei werden die erforderlichen Framework-Bestandteile wie Lego-Bausteine zu einer Menge von Dependencies kombiniert, auf deren Basis der Anwendungscode ergänzt werden kann. So erstellt der folgende Befehl bspw. eine Anwendung, die den klassischen Stack für Microservices inkl. Health Checking enthält:

mvn io.quarkus:quarkus-maven-plugin:create \
  -DprojectGroupId=de.gedoplan.showcase \
  -DprojectArtifactId=quarkus-rest-cdi-jpa \
  -Dextensions="resteasy-jsonb,hibernate-orm,jdbc-h2,smallrye-health"

Das Quarkus-Plugin wird auch im Build des Projektes genutzt. Es erstellt ein ausführbares Jar-File mit dem Anwendungscode sowie ein Verzeichnis, in dem alle benötigten Libraries liegen. Diese Aufteilung – Thin-Jar + Dependencies – ist vorteilhaft bspw. für Docker-Images, weil bei einem erneuten Build der Layer mit den Dependencies nicht erneut gebaut werden muss. Das Jar-File kann einfach über java -jar … gestartet werden.

Hot Reload im Development Mode

So praktisch die Integration des Servers in die Anwendung für den Produktivmodus ist – für die Entwicklungszeit muss die Anwendung nach Anpassungen allerdings gestoppt und neu gestartet werden, da ja kein separater Server existiert, in dem die Anwendung einfach neu deployt werden könnte. Nicht so bei Quarkus: Hier kann die Anwendung im Development Mode gestartet werden:

mvn quarkus:dev.

Quarkus überwacht dann den Quellcode der Anwendung und führt einen automatischen Reload durch, wenn nach Änderungen z. B. wieder auf das Rest API der Anwendung zugegriffen wird. Das geschieht in relativ kurzer Zeit, bei einem vollständigen kleinen Microservice bspw. innerhalb von 1 bis 2 Sekunden. Man kann somit bei laufender Anwendung weiter entwickeln und hat bei jedem Aufruf ohne große Verzögerung den aktuellen Entwicklungsstand im Zugriff.

Einfache (Auto-) Konfiguration

Quarkus-Anwendungen lassen sich mit einer zentralen Konfigurationsdatei im Properties- oder Yaml-Format konfigurieren – ganz ähnlich wie dies in Spring Boot gehandhabt wird. Und die verschiedenen Framework-Teile bringen eine funktionsfähige Grundkonfiguration mit. So wäre in o. a. Anwendung durch die Integration des O/R-Mappers Hibernate und der H2-Datenbank automatisch eine Datasource (auf eine In-Memory-DB) und eine Persistence Unit für die Nutzung in JPA konfiguriert. Die Einstiegshürde ist also bewusst niedrig gelegt: Man kommt schnell zu lauffähigen Ergebnissen und passt die Konfiguration einfach nach Bedarf an – Hot-Reload-fähig natürlich!

Für bestimmte Ausführungssituationen lässt sich die Konfiguration über sog. Configuration Profiles modifizieren. Und auch dafür gibt es teilweise schlau vorbesetzte Werte. So ist z. B. der Standard-Port für Web-Zugriffe 8080. Im Test ist dagegen 8081 voreingestellt, sodass während der Entwicklung im Development Mode auch Tests ausgeführt werden können ohne dass Port-Konflikte entstehen.

Testen

Multi-Unit-Tests und Integrationstests sind im Enterprise-Bereich normalerweise keine leichte Kost. Für klassische JEE-Server wird hier i. d. R. Arquillian eingesetzt, ein Testframework mit umfangreichen Möglichkeiten, das aber aufgrund seiner Flexibilität recht schwierig aufzusetzen ist. Hier geht Quarkus wieder einen anderen, einfacheren Weg. JUnit-5-Testklassen lassen sich über die Annotation @QuarkusTest zu Integrationstests machen: Beim Ablauf fährt die Anwendung automatisch hoch und kann über externe Schnittstellen sofort „Black Box“-getestet werden. Da in der Testklasse zudem sämtliche von CDI gewohnte Injektionsmöglichkeiten zur Verfügung stehen, sind auch White Box Tests unproblematisch. Auch hier ist die Einstiegsschwelle so niedrig, dass Tests schnell und einfach integriert werden können und Testen wieder (?) Spaß macht.

Native Mode

Quarkus ist im normalen JVM-Betrieb schon hinsichtlich der Startzeiten und Ressourceverbräuche optimiert. So benötigt bspw. ein kleiner Service mit einem Rest API und Datenbank-Anbindung über JPA – also ein vollständiger Service, nicht etwa ein belangloser Hello-World-Service – mit Quarkus und OpenJDK unter einer Sekunde bis zum ersten Response, während bei einem klassischen Stack wie Spring Boot gut 4 Sekunden zu verbuchen wären (Abb. 4). Dabei werden etwa 74 MB Memory belegt. Diese von quarkus.io übernommenen Werte lassen sich durchaus mit eigenen Demos belegen. Schauen Sie sich bei Interesse mal unsere Demo unter github.com/GEDOPLAN/micro-comparison an.

Wenn’s jetzt noch kleiner und noch schneller sein soll, was z. B. bei Betrieb in der Cloud von Interesse ist, oder wenn schnell nach Bedarf skaliert werden soll, dann kann eine Quarkus-Anwendung mit Hilfe der GraalVM in Maschinencode kompiliert werden. Das dauert im Build zwar einige Zeit (für die Demo-Anwendung sind’s etwa 3 Minuten), erzeugt im Betrieb aber beeindruckende Ergebnisse: Die Speicherbelegung sinkt nochmals erheblich und die Startzeiten liegen nun im Millisekunden-Bereich (Abb. 4).

Und was ist mit den Standards?

Über die beschriebenen Dinge hinaus bietet Quarkus einen fast ganz normalen Stack aus JEE und MicroProfile an: Rest-Endpoints, JPA-Entities, CDI-Services etc. lassen sich im Programmcode nicht vom klassischen JEE-Stack unterscheiden – Quarkus ist hier eben kein proprietäres Framework, sondern stützt sich vollständig auf dem Standard ab. Das gilt ebenso für die jüngeren Bausteine aus MicroProfile: Health Checking, Monitoring, Resilience etc. funktionieren hier mit Code der identisch auch auf einem WildFly oder Open Liberty eingesetzt werden könnte. Für uns JEE-Experten hat das zwei Vorteile: Wir können unser Wissen weiter einsetzen, ohne umlernen zu müssen. Und die Entscheidung für das Runtime-Framework ist nicht unumstößlich: Stellen wir nach einiger Zeit fest, dass – aus welchen Gründen auch immer – ein Betrieb in einem klassischen Server besser wäre, bedeutet das keine Neuentwicklung, sondern nur eine überschaubare Migration.

Eine Einschränkung muss allerdings erwähnt werden: Ein Teil der Optimierungen wird dadurch erreicht, dass einige Initialisierungen, die ein normaler CDI-Container beim Deployment mit Hilfe von Reflection ausführen würde, bei Quarkus bereits zur Build-Zeit erfolgen. Dieser Augmentation genannte Vorgang setzt einen entsprechend angepassten CDI-Container namens ArC voraus. Er implementiert den CDI-Standard nicht vollständig. Die Einschränkungen sind allerdings praxisorientiert und relativ gut zu akzeptieren. Für den Native Mode gibt es weitere Einschränkungen, die sich daraus ergeben, dass in einem Maschinencode nicht die gleichen dynamischen Möglichkeiten existieren wie in einer JVM, die Bytecode ausführt.

Wie geht’s weiter?

Mit dieser Frage kann zunächst einmal das Quarkus-Ökosystem gemeint sein. Und da tut sich recht viel. Die Releases des Frameworks erscheinen in kurzer Folge (im ersten Quartal von 2020 alleine fünf Final-Releases) und für die Anbindung von Drittsysteme erscheinen in atemberaubender Geschwindigkeit Quarkus-Extensions, z. B. für Kafka, MongoDB, Liquibase, Camel, Scheduling, Mail u. a. m. Auch Spring-Komponenten lassen sich mittlerweile integrieren.

Zum anderen ist nun natürlich die Frage, wie Sie nun weitermachen.


Haben Sie Fragen oder Anmerkungen?
Bitte kontaktieren Sie gerne Dirk Weil:
dirk.weil@gedoplan.de

Gerne beraten wir Sie zum Thema Quarkus und JEE oder qualifizieren Ihre Mitarbeiter.
Bitte kontaktieren Sie Tim Neumann:
tim.neumann@gedoplan.de

Aktuelle Kurse zum Thema "Quarkus"

Microservices mit Quarkus - kompakt
Jakarta EE mit MicroProfile kombinieren, um Microservices und verteilte Systeme für Quarkus zu entwickeln
Microservices mit Quarkus - Grundlagen
-> Kursseite

Microservices mit Quarkus - Grundlagen

Microservices und verteilte Systeme schnell und einfach entwickeln mit Quarkus, Jakarta EE und MicroProfile
-> Kursseite

Microservices mit Quarkus - Aufbau
Microservices und verteilte Systeme schnell und einfach entwickeln mit Quarkus, Jakarta EE und MicroProfile
-> Kursseite

IT-Vorträge für Sie und Ihr Team!

Die Vorträge dauern in der Regel 60 Minuten und geben Einblick in neue Technologien und Möglichkeiten im Umgang mit Java. Sie werden anschaulich und praxisnah dargestellt.

-> IT-Vorträge

Expertenkreise Java: IT-Vorträge seit 2008!

Im Expertenkreis Java dreht sich alles um das Thema Java: Architekturen, Entwicklungstools, Erfahrungsberichte, Standards und einiges mehr. Die Teilnehmer des Expertenkreises wechseln sich mit Referaten zu den einzelnen Themen ab. Themen, Tiefe und Tempo bestimmt der Expertenkreis selbst.

-> Weitere Informationen zum EK Java

Unser Java EE / JEE Blog

Hier finden Sie alle Neuigkeiten, Ideen und Kommentare rund um Java EE / JEE.

-> Java-Blog

Neu: Mini-Schulungen Remote - schnell ein Thema lernen?

Unsere Mini-Schulungen sind dafür gedacht, "schnell" und unkompliziert ein Kurs-Kapitel zu erlernen.

-> Unsere Mini-Schulungen

Remote + maßgeschneidert?

Alle Kurse gibt es als
ind. Remote-Firmenschulungen.

Kontaktieren Sie mich oder
nutzen Sie unseren
Schulungskonfigurator!

030 / 755 49 188

Tim.Neumann@GEDOPLAN.de