Vauban repose sur un principe simple : tout ce qui peut être calculé à la compilation l’est. Aucune réflexion à chaud, aucun proxy dynamique, aucune librairie de bytecode externe. Cette page décrit les choix d’implémentation qui supportent cette discipline.
Codegen via Class-File API et APT
CDI 4.1 décrit un modèle d’objets richement réflexif : Bean<T>, BeanManager, InjectionPoint, AnnotatedType. Vauban refuse d’évaluer ce modèle au runtime. Il le compile.
Deux outils interviennent à process-classes :
-
vauban-indexer— parcourt le module-path à la compilation et produit un fichier d’index (META-INF/vauban/index.bin). L’équivalent statique duBeanArchiveruntime de Weld. Zéro dépendance. -
vauban-processor—javax.annotation.processing.Processorqui consomme l’index et émet du bytecode via la Class-File API (JEP 484). Pas d’ASM, pas de Byte Buddy, pas de Gizmo.
Pour chaque bean, le processeur génère :
| Artefact généré | Rôle |
|---|---|
|
Implémente |
|
Sous-classe générée pour les scopes normaux. Intercepte chaque méthode publique et délègue au contexte actif via |
|
Pour chaque méthode |
|
Pour chaque méthode |
|
Le drift entre |
Pipeline APT — diagramme de séquence
Tout l’index, toute la grille d’injection, tous les proxies sont écrits avant que javac ne finisse son travail.
Séquence de bootstrap runtime
L'`ApplicationContext` est créé en mémoire, sans réflexion, sans ouverture de packages.
Modèle de threading
Vauban utilise les virtual threads (JEP 444) pour deux usages :
-
Observateurs asynchrones — chaque
@ObservesAsyncest dispatché sur unExecutors.newVirtualThreadPerTaskExecutor()interne auEventDispatcher. Pas de pool de threads plateforme, pas de file d’attente bornée. -
Contexte de requête — quand Vauban est embarqué dans Cassini ou Foy, le
RequestContextest porté par unScopedValue(JEP 487) plutôt qu’unThreadLocal. Cela permet aux virtual threads structurés de propager le contexte sans fuite.
|
Le passage |
Compatibilité AOT
Aucun Class.forName, aucun Method.invoke, aucun Class.getDeclaredFields() n’est appelé à chaud. Le runtime utilise :
-
des invocations directes sur les
_Factorygénérés ; -
des
MethodHandlespour l’invocation des@PostConstruct,@PreDestroy, observateurs et intercepteurs ; -
aucun chargement dynamique de classe au-delà du
ServiceLoaderstandard.
Conséquence : Vauban se compile en image native GraalVM sans fichier reflect-config.json. Il est compatible avec Project Leyden CDS et avec une image JLink minimale.
Modules JPMS exportés
| Module | Exports principaux |
|---|---|
|
|
|
|
|
|
|
(interne, requiert |
|
|
|
Implémentation chiffrée AES-256-GCM du SPI (optionnelle) |
Voir la référence pour la liste exhaustive.
Sources
-
vauban-core — runtime du container
-
vauban-processor — APT et générateurs Class-File API
-
vauban-indexer — scanner build-time
-
BUG.md — bugs reproductibles tracés (VAU-PRX-002, VAU-INJ-001)