vidocq-runtime-spi exposes the interfaces and annotations an extension consumes to contribute to the runtime. It is the only module a user-side extension must declare in its JPMS requires.

Coordinates

Artefact

io.vidocq.runtime:vidocq-runtime-spi:0.1.0-SNAPSHOT

JPMS module

io.vidocq.runtime.spi

Source

vidocq-runtime-spi/src/main/java/io/vidocq/runtime/spi/

Public surface

List indexed from the existing sources:

Type Role

VidocqExtension

Marker interface for ServiceLoader. An extension implements configure(ExtensionContext).

ExtensionContext

Contribution API — BuildItem registry, configuration access, current phase.

VidocqConfiguration

Interface read at build time to resolve extension-specific options.

config.VidocqConfig

MicroProfile Config facade — getValue(), getOptionalValue(), Converter<T>, ConfigSource.

config.ConfigSource

Configuration source (analogous to MicroProfile, re-exposed).

config.Converter<T>

Typed conversion of configuration values.

Writing an extension — skeleton

package com.example.greeting;

import io.vidocq.runtime.spi.VidocqExtension;
import io.vidocq.runtime.spi.ExtensionContext;
import io.vidocq.runtime.spi.config.VidocqConfig;

public class GreetingExtension implements VidocqExtension {

    @Override
    public void configure(ExtensionContext ctx) {
        VidocqConfig cfg = ctx.config();
        String prefix = cfg.getValue("greeting.prefix", String.class);

        ctx.produce(new GreetingPrefixBuildItem(prefix));
    }
}

JPMS 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. The vidocq-runtime-maven-plugin detects the JPMS provides, indexes the extension and includes it in the generated bootstrap.

Build step purity model

A @BuildStep must be:

  • deterministic — same inputs yield same outputs;

  • pure — no side effects outside BuildProducer;

  • idempotent — replayable safely.

This discipline guarantees that generated bytecode is reproducible and compatible with Maven caches and immutable artefacts.

Recorders

A recorder is a @Recorder class whose method invocations are recorded rather than executed. The engine generates, for every call, an invokevirtual bytecode fragment in the RuntimeBootstrap class. See Internals for the full mechanism.

@Recorder
public class GreetingRecorder {
    public RuntimeValue<Greeter> create(String prefix) {
        return new RuntimeValue<>(new Greeter(prefix));
    }
}

Next steps