vidocq-runtime-spi exposes the interfaces an extension implements to contribute to the runtime. It is the only module a user-side extension must declare in its Java Modules requires.
Coordinates
Artefact |
|
Java module |
|
Source |
|
Public surface
List indexed from the existing sources:
| Type | Role |
|---|---|
|
The extension point — lifecycle interface with |
|
Handed to |
|
String-property view passed to |
|
Typed configuration API aligned with MicroProfile Config concepts — |
|
Pluggable configuration sources (analogous to MicroProfile), also discovered via |
|
Typed conversion of configuration values. |
|
Application-side entry points — the class run inside the Vauban application layer by |
Writing an extension — skeleton
An extension overrides only the hooks it needs; every lifecycle method has an empty default implementation.
package com.example.greeting;
import io.vidocq.runtime.spi.VidocqExtension;
import io.vidocq.runtime.spi.VidocqConfiguration;
import io.vidocq.runtime.spi.ExtensionContext;
public class GreetingExtension implements VidocqExtension {
private String prefix;
@Override
public String name() {
return "greeting";
}
@Override
public void configure(VidocqConfiguration config) {
// called before CDI boot — read your keys
this.prefix = config.property("vidocq.greeting.prefix", "Hello");
}
@Override
public void onStart(ExtensionContext ctx) {
// the CDI container is up — resolve beans, mount handlers
Greeter greeter = ctx.container().select(Greeter.class);
greeter.setPrefix(prefix);
}
@Override
public java.util.Set<String> configKeys() {
return java.util.Set.of("vidocq.greeting.prefix");
}
}
Java Modules declaration in module-info.java:
module com.example.greeting {
requires io.vidocq.runtime.spi;
provides io.vidocq.runtime.spi.VidocqExtension
with com.example.greeting.GreetingExtension;
}
That is all. At startup the runtime’s ExtensionLoader discovers the provides directive through java.util.ServiceLoader, sorts all extensions by ascending priority(), and VidocqBootstrap drives the lifecycle: configure → beforeStart → onStart, then onStop in reverse order at shutdown.
Ordering with priority()
Priorities express real ordering constraints between extensions. The built-in HTTP stack illustrates the idiom: the Chappe engine prepares the server at priority 100, contributors such as the Cassini REST extension mount their handlers around priority 500, and the listener bootstrap opens the sockets last at priority 10 000. Pick a value between the extensions you must run after and before; unrelated extensions can keep the default 1000.
Configuration keys audit
Declaring your keys in configKeys() is optional but recommended: the runtime’s ConfigKeyAudit compares every configured vidocq. key against the union of declared keys and warns at startup about keys nobody consumes — the typical typo that otherwise silently keeps the default. Entries ending in declare a prefix ("vidocq.greeting.*").
Next steps
-
Concepts — formal vocabulary
-
Reference — public SPI table
-
Built-in extensions — concrete SPI consumption examples