skip to content

How do you enforce a minimum Maven and Java version, and what does the version range syntax mean?

level: juniorimportance: must knowfreq 50%

answer

  1. [ ] inclusive, ( ) exclusive
  2. [3.9,) = 3.9 or higher
  3. bare 3.9 = soft minimum not pin
  4. requireJavaVersion = build JVM not <release>
  5. add <message> for guidance

basics

~10 s

Use 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
xml
<requireJavaVersion>
  <version>[21,)</version>
  <message>This project requires JDK 21 or newer.</message>
</requireJavaVersion>

go deeper

for a junior

Can add requireMavenVersion/requireJavaVersion with a simple [x,) range.

for a middle

Understands inclusive/exclusive interval syntax and the bare-version gotcha.

for a senior

Distinguishes the build JVM from the compile target and adds actionable <message> text.

for a principal

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.

context