Maven reference
StoatFlow gives Maven projects the same build conventions as the Gradle plugin, through three published artifacts under io.stoatflow. This page enumerates them; for the setup walkthrough see Project setup.
The three artifacts
| Artifact | What it is |
|---|---|
io.stoatflow:stoatflow-bom | A Maven BOM (<dependencyManagement> import) that aligns the StoatFlow modules with their tested kafka-clients / rocksdbjni / micrometer versions and imports the JUnit BOM. |
io.stoatflow:stoatflow-parent | The convention parent POM — JDK 25 + --enable-preview, kotlin-maven jvmTarget 25, the shade fat JAR, the surefire/failsafe IntegrationTest tag-split, exec:exec run, and the stoatflow-docker / stoatflow-native profiles. Imports the BOM for you. |
io.stoatflow:stoatflow-maven-plugin | Four goals (prefix stoatflow) for the things XML can't express: RocksDB auto-detection, the staged native docker build, and the forked preview-flag run. |
Set up
Inherit from the parent and declare your dependency (its version comes from the BOM the parent imports — so you omit it):
<!-- pom.xml -->
<parent>
<groupId>io.stoatflow</groupId>
<artifactId>stoatflow-parent</artifactId>
<version>REPLACE-WITH-CURRENT-RELEASE</version> <!-- literal — Maven can't resolve a property in <parent> -->
<relativePath/>
</parent>
<properties>
<stoatflow.mainClass>com.example.Main</stoatflow.mainClass>
</properties>
<dependencies>
<dependency>
<groupId>io.stoatflow</groupId>
<artifactId>stoatflow-runtime</artifactId>
<!-- version managed by the imported stoatflow-bom -->
</dependency>
<dependency>
<groupId>io.stoatflow</groupId>
<artifactId>stoatflow-test-utils</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
The current release is 1.0.0-alpha.16 — substitute it for the REPLACE-WITH-CURRENT-RELEASE placeholder (the <parent> version must be a literal; Maven does not interpolate properties in parent coordinates). For a Kotlin project, point Maven at src/main/kotlin, add the kotlin-stdlib (version ${kotlin.version}, from the parent), and use the …Kt main class — the parent already configures kotlin-maven-plugin (jvmTarget 25) and binds its compile/test-compile phases.
mvn stoatflow:…). To call the plugin's standalone goals by their short prefix, add io.stoatflow to <pluginGroups> in your ~/.m2/settings.xml:<pluginGroups>
<pluginGroup>io.stoatflow</pluginGroup>
</pluginGroups>
mvn io.stoatflow:stoatflow-maven-plugin:run.What the parent configures
| Convention | Detail |
|---|---|
| Compiler | --release 25 + --enable-preview (javac). |
| Kotlin | kotlin-maven-plugin jvmTarget 25 (no preview flag — that's javac-only). |
| Fat JAR | maven-shade-plugin produces a <finalName>-all.jar with the Main-Class manifest + merged service files. |
| Unit tests | maven-surefire-plugin on JUnit Platform with the preview/native-access JVM args; excludes @Tag("IntegrationTest"). |
| Integration tests | maven-failsafe-plugin runs only @Tag("IntegrationTest"), bound to integration-test / verify. |
| Run | exec-maven-plugin configured for exec:exec — a forked JVM so --enable-preview applies (exec:java runs in Maven's own JVM and can't). |
| Profiles | stoatflow-docker (Jib image at package), stoatflow-native (native compile at package), and host-arch selection. |
Properties reference
Set these in your <properties>. Defaults come from the parent.
| Property | Default | Description |
|---|---|---|
stoatflow.mainClass | (required) | Application entry point. stoatflow:configure fails the build if unset. |
stoatflow.docker.imageName | ${project.artifactId} | Image name. Tagged latest + <version>. |
stoatflow.docker.port | 8080 | Exposed container port. |
stoatflow.docker.user | 1000:1000 | Non-root run-as user. |
stoatflow.docker.baseImage | eclipse-temurin:25-jre-noble | JVM base image. |
stoatflow.docker.stateDir | /data/state | RocksDB state dir → STOATFLOW_STATE_DIR. |
stoatflow.docker.rocksdbMb | empty = auto-detect | Off-heap RocksDB MiB → STOATFLOW_ROCKSDB_MB. Empty = 256 if RocksDB on the classpath, else omitted; set a value to force; 0 omits. |
stoatflow.docker.reproducibleBuild | true | Pin creationTime to the HEAD commit. |
stoatflow.docker.jvmFlags | -XX:+UseG1GC | Container GC flag (preview/native-access always added). |
stoatflow.nativeImage.gc | empty | --gc value for the native docker build (e.g. G1; needs Oracle GraalVM). |
stoatflow.nativeImage.runtimeTarget | runtime | Docker target stage for native-docker-build (runtime or runtime-lean). |
stoatflow.nativeImage.removeInitializeAtRunTime | empty | Comma-separated --initialize-at-run-time entries to drop from the curated base. |
docker.rocksdbMb, creationTime, and the docker executable carry no <properties> default. Maven's model interpolator bakes <properties> into the plugin <configuration>before any Mojo runs, which would override the auto-detection — so these stay undefined and resolve live from stoatflow:configure. To add native flags (the counterpart of Gradle's additionalInitializeAtRunTime), extend the native-maven-plugin<buildArgs> in your POM, or ship reachability metadata with your value classes (see Native image → Custom serde metadata).Goals
| Goal | Bound to | Purpose |
|---|---|---|
stoatflow:configure | initialize (both profiles) | Auto-detects RocksDB → STOATFLOW_ROCKSDB_MB, probes the docker executable (macOS), computes the reproducible creationTime, stages the effective native argfile, and validates mainClass. |
stoatflow:copy-entrypoint | prepare-package (docker profile) | Stages the container-aware heap entrypoint into target/jib-extra/app/. |
stoatflow:native-docker-build | standalone | Stages the native build context (prebuilt JAR + argfile + Dockerfile.native + entrypoint) and runs the host-arch docker build. |
stoatflow:run | standalone | Forks a JVM with the preview flags + your runtime classpath + mainClass. |
Build commands
| Command | Result |
|---|---|
mvn package | Compiles + the fat JAR target/<name>-<version>-all.jar. |
mvn -Pstoatflow-docker package | Fat JAR and a Jib image to your local Docker daemon — one command. |
mvn -Pstoatflow-native package | A GraalVM native binary via native-maven-plugin (host toolchain). |
mvn stoatflow:native-docker-build | A native image built inside Docker from the prebuilt fat JAR (run mvn package first). |
mvn stoatflow:run | The app in a forked JVM with --enable-preview. |
-P, not POM <properties>. Maven <activation> reads system/user properties, not your project's <properties> — so a <stoatflow.docker.enabled> flag does not turn the build on. Activate with mvn -Pstoatflow-docker … (or -Dstoatflow.docker.enabled=true). The stoatflow-docker profile binds the Jib dockerBuild goal to package, which is why mvn -Pstoatflow-docker package is the whole image build.Using just the BOM
If you don't want the parent POM (you already have a corporate parent, say), import the BOM directly for version alignment and configure the toolchain + flags yourself — the DIY path is in Installation → Option B:
<properties>
<stoatflow.version>REPLACE-WITH-CURRENT-RELEASE</stoatflow.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.stoatflow</groupId>
<artifactId>stoatflow-bom</artifactId>
<version>${stoatflow.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Version compatibility
The parent pins the build plugins it uses. As of 1.0.0-alpha.16 the pins are:
| Plugin | Version |
|---|---|
| Maven | 3.8+ (3.9.x recommended) |
| jib-maven-plugin | 3.5.1 |
| native-maven-plugin | 1.1.0 |
| maven-shade-plugin | 3.6.0 |
| kotlin-maven-plugin | 2.4.0 |
| surefire / failsafe | 3.5.2 |
Related
- Project setup — the setup walkthrough (Gradle and Maven).
- Gradle plugin reference — the same conventions for Gradle projects.
- Docker · Native image — the container and GraalVM build guides.
Gradle plugin reference
The io.stoatflow convention plugin — the full stoatflow { } extension DSL, the plugins and JVM flags it applies, the tasks it contributes, and the Docker and native-image defaults.
Kafka Streams compatibility matrix
Operator-by-operator parity between the StoatFlow DSL and the Kafka Streams DSL — implemented, partial, not yet implemented, deprecated, incompatible, and StoatFlow extensions.