Zum Inhalt springen

GraalVM Native Image

Kurzantwort: CDMS wird produktiv als natives Binary betrieben – kürzere Startzeit und deutlich weniger RAM (Erfahrungswert: rund 400 MB auf unter 200 MB). Der Preis ist, dass jede Reflexion vorab bekannt sein muss. Die festen Modultypen registrieren die Module selbst, die anwendungsspezifischen Typen registriert der Generator.


Gruppewer registriertwo
Feste Modultypen: Basisklassen (AbstractEntityModel, AbstractSystemModel, AbstractTenantModel, AbstractUserModel), Envers-TypenPersistenzmodulaot.CdmsPersistenceRuntimeHints, eingebunden über @ImportRuntimeHints in aot.CdmsPersistenceAotConfiguration
Konkrete Entities aus der EntityRegistryGeneratorJpaNativeHints
DTOs und Payloads (Jackson)GeneratorJacksonNativeHints
Enums, die als Filterwerte über valueOf(String) laufenGeneratorJpaNativeHints
Weitere reflexiv genutzte Typen der AnwendungAnwendungeigene RuntimeHints-Klasse
Aktivierung im ProjektScaffoldconfig/NativeHintsConfiguration

Die Basisklassen brauchen die Registrierung, weil ihre geerbten Accessoren (get_createdOn, getId, get_userId, …) bei jeder Entity reflexiv aufgerufen werden.

StelleArt
System-LayerMethodHandles.lookup().findVirtual(...) für jeden Getter/Setter
Persistenzgecachte Getter/Setter (GETTER_CACHE, SETTER_CACHE) inklusive der Unterstrich-Systemfelder
JacksonDeserialisierung von DTOs und Payloads
HibernateEntity-Verarbeitung, Envers
HooksInstanziierung von Feld-Hooks über getConstructor().newInstance()

Das ist der Grund, warum Native Image bei CDMS kein Nebenthema ist: Der Kern arbeitet durchgehend reflexiv über generierte Modelle.

Terminal-Fenster
# benötigt GraalVM Community 24
./mvnw clean package -Pnative -DskipTests
./mvnw -Pnative native:compile -DskipTests

In der CI läuft der Build im Image native-image-community:24; das Ergebnis target/cdms wandert in ein debian:bookworm-slim-Image.

SymptomUrsache / Abhilfe
NoClassDefFoundError oder Reflexionsfehler nur im nativen Imagefehlende Hints – @RegisterReflectionForBinding bzw. RuntimeHints ergänzen
Jackson kann ein Payload nicht deserialisierenKlasse fehlt in JacksonNativeHints
Enum-Filter schlägt fehlvalueOf(String) nicht registriert
Build verlangt GraalVMJDK auf GraalVM Community 24 stellen
  1. Neue reflexiv genutzte Typen brauchen Hints. Wer eine eigene Klasse per Reflexion oder Jackson anspricht, registriert sie – am besten dort, wo sie entsteht.
  2. Der Generator ist die richtige Stelle für Modelltypen. Manuell gepflegte Listen laufen mit dem nächsten Modell auseinander.
  3. Der Beweis ist der Build. Nur ein GraalVM-Build in der CI zeigt, ob das Image wirklich läuft.
AspektJVMNative
StartzeitSekundenBruchteile davon
RAM nach dem Start~400 MB (gemessener Fall)< 200 MB
Build-Dauerkurzdeutlich länger
Reflexionfreinur mit Hints

In Kubernetes mit vielen kleinen Diensten ist der Speicherunterschied der ausschlaggebende Punkt.