Cette page couvre les usages avancés de Vidocq Runtime au-delà du Hello world : packaging via le vidocq-runtime-maven-plugin (jlink, jpackage, Docker), configuration via https://microprofile.io/specifications/microprofile-config/, observabilité (https://microprofile.io/specifications/microprofile-health/, https://microprofile.io/specifications/microprofile-metrics/, https://microprofile.io/specifications/microprofile-open-api/), profils, et préparation AOT.

Packaging avec vidocq-runtime-maven-plugin

Le plugin Maven expose trois cibles de packaging. Voir la fiche dédiée pour l’inventaire complet et le détail JLINK.md interne au repo.

Goal Sortie Démarrage typique

vidocq:jlink

target/dist/ (binaire + runtime Java embarqué, ~40 Mo)

~4 s

vidocq:jpackage

target/installer/<name>.app ou .exe/.msi/.deb/.rpm

~1 s (CDS)

vidocq:docker

target/Dockerfile distroless basé sur distroless/base-debian12:nonroot

~50 Mo image

Quick start (depuis vidocq-runtime-cassini-rest-example) :

cd vidocq-runtime-examples/vidocq-runtime-cassini-rest-example
./mvnw -ntp package -DskipTests
./target/dist/bin/todo-app

Applications multi-modules (dépendances scannées)

Les applications hexagonales et multi-modules gardent en général leurs modules métier et adaptateurs spec-only — uniquement les API Jakarta EE / MicroProfile, aucune dépendance Vidocq, aucun APT Vidocq — et concentrent tout le spécifique runtime dans un petit module principal. Ce module principal demande à vidocq:generate de scanner les modules applicatifs et de produire la glu CDI/REST pour eux :

<execution>
    <id>generate</id>
    <goals><goal>generate</goal></goals>
    <configuration>
        <scanDependencies>
            <scanDependency>com.acme:my-rest-adapter</scanDependency>
            <scanDependency>com.acme:my-domain</scanDependency>
        </scanDependencies>
    </configuration>
</execution>

Deux règles pour le module-info.java de chaque module scanné — en se rappelant que le système de modules Java ne permet à un module d'`opens` (ou d'`exports`) que les packages qu’il possède : impossible d’ouvrir le package d’un autre module depuis le module principal, c’est pourquoi l'`opens` mono-module montré dans Getting started doit migrer dans le module qui contient les classes.

module com.acme.rest.adapter {
    exports com.acme.rest;          // les resources
    exports com.acme.rest.dto;      // JSON-B lit les records via leurs accesseurs publics
    requires jakarta.cdi;
    requires jakarta.ws.rs;

    // Le runtime consommateur génère/réfléchit la plomberie CDI de ces beans.
    // Un `opens` non qualifié ne nomme aucun module runtime : le module reste
    // spec-only, et les runtimes classpath l'ignorent totalement.
    opens com.acme.rest;
}
Nouveau en 0.3.0-SNAPSHOT

Les classes que vidocq:generate produit pour les dépendances scannées (proxies clients, intercepteurs) vivent dans des packages possédés par ces dépendances. Depuis 0.3.0 le plugin les tient automatiquement hors du module principal :

  • vidocq:generate les parque dans target/vidocq-patches/<artifactId>/ (ligne de log : JPMS: parked N generated class(es) of '…') ;

  • vidocq:package et vidocq:jlink copient/staguent des jars de dépendance enrichis qui embarquent leurs propres classes générées — les packages existant déjà dans ces jars, leur descripteur de module reste exact et le module path ne voit jamais de split package ;

  • vidocq:dev ajoute automatiquement les options --patch-module correspondantes à la JVM fille.

Aucune configuration supplémentaire au-delà de <scanDependencies>.

En 0.2.0 (publiée)

Vidocq 0.2.0 laisse les classes générées dans le target/classes du module principal, ce qui crée un split package illégal sur le module path : le boot layer échoue avec ResolutionException: Module <main> contains package <pkg>, module <dep> exports package <pkg> — ou, si la dépendance n’est pas requires, ses beans sont silencieusement absents (HTTP 404). Le contournement en 0.2.0 consiste à faire à la main ce que 0.3.0 fait nativement :

  1. déplacer les classes des packages étrangers hors de target/classes avant la construction du jar (p. ex. maven-antrun-plugin en prepare-package — les retirer après coup ne suffit pas, car maven-jar-plugin enregistre les packages dans l’attribut ModulePackages du module-info.class) ;

  2. lancer avec --patch-module <module.dep>=<dir> pour chaque dépendance, p. ex. via le <jvmArgs> du goal package pour les scripts de lancement générés.

Configuration MicroProfile

Vidocq Runtime implémente https://microprofile.io/specifications/microprofile-config/. Hiérarchie des sources, du plus prioritaire au moins prioritaire :

Ordinal Source Description

400

SystemPropertiesConfigSource

-Dkey=value

300

EnvConfigSource

Variables d’environnement (KEY_NAME)

250

ExternalFileConfigSource

${java.home}/conf/vidocq.properties (image jlink)

100

PropertiesFileConfigSource

vidocq.properties du classpath

ExternalFileConfigSource permet de surcharger un binaire jlink/jpackage déployé sans rebuilder, simplement en éditant le fichier conf/vidocq.properties à côté du launcher. Une ligne de log au boot trace le chargement effectif.

Health

@Liveness
@ApplicationScoped
public class DatabaseHealth implements HealthCheck {
    @Inject DataSource ds;

    @Override
    public HealthCheckResponse call() {
        try (Connection c = ds.getConnection()) {
            return HealthCheckResponse.up("database");
        } catch (SQLException e) {
            return HealthCheckResponse.down("database");
        }
    }
}

Endpoints exposés : /q/health, /q/health/live, /q/health/ready, /q/health/started (jalon en cours, voir TCK).

Metrics

Implémentation https://microprofile.io/specifications/microprofile-metrics/ en cours. Les compteurs et histogrammes seront enregistrés au build time par l’extension vidocq-runtime-metrics-extension. Endpoint Prometheus /q/metrics.

OpenAPI

L’extension vidocq-runtime-openapi-extension (jalon courant) génère le document OpenAPI à la compilation à partir des annotations Jakarta REST + MicroProfile OpenAPI. Endpoint /q/openapi.

Profils

Convention MicroProfile : préfixer une clé par %<profil>. pour la scoper.

vidocq.http.port=8080
%dev.vidocq.http.port=8081
%prod.vidocq.http.port=80

Activation via -Dvidocq.profile=dev ou la variable VIDOCQ_PROFILE.

Déploiement Docker

Image distroless minimale produite par vidocq:docker :

./mvnw -ntp package -Dvidocq.docker.build=true
docker run --rm -p 8080:8080 \
    -e VIDOCQ_CONFIG_DIR=/etc/myapp \
    -v $(pwd)/conf:/etc/myapp:ro \
    example/my-app:1.0.0

Le base image distroless/base-debian12:nonroot n’a ni shell ni package manager — surface d’attaque réduite. L’utilisateur nonroot (UID 65532) est imposé.

AOT — GraalVM et Leyden

  • Leyden CDS — supporté de série. La génération statique Class-File API produit un bytecode parfaitement archivable.

  • GraalVM native-image — la stratégie zéro-réflexion + zéro-proxy de Vidocq Runtime minimise les reachability-metadata. Voir vidocq/JLINK.md pour les pré-requis runtime (logging.properties, Java Modules nommés, records sérialisés).

Pour aller plus loin