How do you enforce a minimum Maven and Java version, and what does the version range syntax mean?
answer
- [ ] inclusive, ( ) exclusive
- [3.9,) = 3.9 or higher
- bare 3.9 = soft minimum not pin
- requireJavaVersion = build JVM not <release>
- add <message> for guidance
basics
~10 sUse the requireMavenVersion and requireJavaVersion rules with a version range. For example [3.9,) means '3.9 or higher'. The build fails if the running Maven or JDK is outside the range.
solid answer
~40 s`requireMavenVersion` checks the Maven runtime; `requireJavaVersion` checks the JDK running the build (the Java version Maven executes under, not your compiler `<release>`). Both accept Maven's version-range syntax: square brackets are inclusive, parentheses exclusive, and an open end is allowed. `[3.9,)` means >= 3.9; `[21,)` means JDK 21+; `[17,21)` means 17 inclusive up to but excluding 21. A bare version like `3.9` is treated as a *recommendation* (>= ), not an exact pin, which surprises people — use `[3.9]` for an exact match. These rules prevent subtle failures from old toolchains and make CI and local builds consistent. Note `requireJavaVersion` validates the build JVM, so pairing it with the compiler plugin's `<release>` is good practice.
code
xml · 4 lines<requireJavaVersion>
<version>[21,)</version>
<message>This project requires JDK 21 or newer.</message>
</requireJavaVersion>go deeper
Can add requireMavenVersion/requireJavaVersion with a simple [x,) range.
Understands inclusive/exclusive interval syntax and the bare-version gotcha.
Distinguishes the build JVM from the compile target and adds actionable <message> text.
Standardises toolchain ranges org-wide and coordinates them with toolchains.xml / CI runner images.
## The two version rules - **requireMavenVersion** — validates the version of the **Maven runtime** executing the build. - **requireJavaVersion** — validates the version of the **JDK that is running Maven** (i.e. the `java` process). This is *not* the same as the bytecode target you set with the compiler plugin's `<release>`/`<source>`/`<target>`; a build could run on JDK 21 but compile to Java 17. ## Version-range syntax (shared across Maven) Maven uses interval notation: - `[` / `]` = **inclusive** boundary. - `(` / `)` = **exclusive** boundary. - `,` separates lower and upper bounds; an empty side means unbounded. Examples: - `[3.9,)` → 3.9 and anything higher. - `[21,)` → JDK 21+. - `[17,21)` → 17 up to but not including 21. - `[3.9]` → exactly 3.9. - `3.9` (no brackets) → treated as a **soft minimum** (>= 3.9), NOT an exact pin — a common gotcha. ## Configuration ```xml <rules> <requireMavenVersion> <version>[3.9,)</version> <message>Use Maven 3.9+ — older versions break the reproducible-build plugin.</message> </requireMavenVersion> <requireJavaVersion> <version>[21,)</version> </requireJavaVersion> </rules> ``` ## The optional message Most rules accept a `<message>` element that replaces the generic failure text — invaluable for telling a developer *what to do* (e.g. 'install JDK 21'). ## Why enforce both Without the rule, a teammate on an old JDK gets a confusing compile or runtime error far downstream. With it, the build halts at `validate` with a precise, actionable message — the same on every machine and in CI.
- Does requireJavaVersion enforce the bytecode target level?No — it checks the JDK running Maven. The bytecode target is controlled separately by the compiler plugin's <release>.
- What does the bare version '3.9' mean versus '[3.9]'?'3.9' is a soft minimum (>= 3.9); '[3.9]' is an exact match. To pin exactly, use the bracketed form.
saying these in an interview costs you the question
- Believing requireJavaVersion sets/overrides the compile target.
- Assuming a bare version number means an exact version — it is a recommended minimum.