Vidocq Runtime adopts the extension vocabulary popularised by Quarkus, but implements it on a 100 % JDK foundation (CDI Lite via Vauban + standard Class-File API, JEP 484). This page defines the terms used throughout the documentation.

Extension

An extension is a Maven module that contributes to the runtime via the vidocq-runtime-spi SPI. It manifests as:

  • a fragment of bytecode and configuration injected into the boot sequence;

  • one or more classes annotated @BuildStep running at compile time;

  • optionally one or more @Recorder classes producing bytecode replayed at startup.

An extension is static: it loads nothing dynamically at runtime. Everything it contributes is resolved at mvn package.

Build step

A build step is a method annotated @BuildStep inside an extension. It:

  • consumes zero, one or more BuildItem parameters;

  • produces one or more BuildItem via return value or BuildProducer<T>;

  • runs at compile time, in a topological graph computed by vidocq-runtime-core.

The orchestration engine guarantees that a build step runs only after its inputs are produced and before its outputs are consumed. Producer/consumer pairs define the graph edges.

BuildItem

A BuildItem is the exchange unit between build steps. Three families:

  • SimpleBuildItem — a single producer allowed (e.g. JaxRsApplicationBuildItem);

  • MultiBuildItem — N producers allowed (e.g. BeanBuildItem, ResourceBuildItem);

  • SymbolicBuildItem — phase marker without payload (e.g. ApplicationStartBuildItem).

Recorder

A recorder is a class annotated @Recorder whose method invocations are recorded rather than executed. At compile time, every method call on a recorder is serialised as invokevirtual bytecode in a generated class produced via Class-File API. At startup, that bytecode is replayed — no reflection, no proxy.

Recorders distinguish two phases:

  • @Record(STATIC_INIT) — runs early, in the static initialiser of the generated class;

  • @Record(RUNTIME_INIT) — runs at startup, after external configuration is loaded.

Lifecycle phase

The Vidocq Runtime boot sequence comprises five ordered phases:

  1. Config — resolution of MicroProfile Config sources, external override.

  2. Extensions init — each extension receives ExtensionContext and publishes its runtime BuildItem.

  3. CDI start — Vauban starts the BeanManager (beans were already indexed at build time).

  4. Transport bind — Chappe opens HTTP/1.1, H2, H3 listeners per config.

  5. Routes register — Cassini and Foy register REST resources and servlets; Mansart opens the JDBC pool.

Notable differences from Quarkus

Aspect Quarkus Vidocq Runtime

Runtime CDI

ArC (custom)

Vauban (CDI 4.1 Lite, TCK 774/774)

Bytecode generation

Gizmo (ASM)

JDK Class-File API (JEP 484)

HTTP transport

Vert.x

Chappe on virtual threads

JSON

Jackson

Champollion (JSON-B 3.0)

Persistence

Hibernate ORM/Reactive

Mansart (Jakarta Data 1.0 + JDBC)

Minimum JDK

17

25 (LTS)

Native JPMS

No

Yes — module-info.java everywhere

Composition of the six bricks

Vidocq Runtime invents no runtime; it composes the six foundational bricks. The vidocq-runtime-cassini-rest-extension extension, for example, registers a build step that:

  • consumes CdiBeanIndexBuildItem produced by vidocq-runtime-vauban-extension;

  • triggers static routing generation in Cassini;

  • produces HttpRouteBuildItem consumed by vidocq-runtime-chappe-webserver-extension.

This BuildItem grammar makes the ecosystem homogeneous while every brick remains self-contained in its own repo.

Next steps

  • Internals — boot sequence step by step

  • SPI — how to write an extension

  • Reference — standard annotations and BuildItem