Maven Core Runtime Requirement Changes to Java 17 in Maven 4.0.0
0 reputation · 02 May 2020, 18:00 UTC
0 reputation · 02 May 2020, 18:00 UTC
The goal is to understand whether a Maven 4.0.0 build can continue to compile source code with Java 8 while the Maven process itself runs on Java 17, using the toolchains mechanism to decouple the compilation JDK from the runtime JDK. Maven 4.0.0 enforces a hard runtime baseline of Java 17, but the toolchains.xml configuration can still declare a Java 8 toolchain for the maven-compiler-plugin. This does not change the JVM used to launch Maven, and projects that rely on the maven-wrapper may automatically upgrade to a 4.x distribution, breaking CI images that only provide Java 8 or 11.
Uncertainty remains about which core or third‑party plugins require recompilation against the new maven‑plugin‑api 4.0 and whether declaring a Java 8 toolchain guarantees successful compilation when those plugins are loaded. Additionally, teams need a way to verify plugin compatibility before promoting the wrapper to a 4.x version without introducing build failures. Does declaring a Java 8 toolchain in toolchains.xml allow successful compilation when Maven 4 runs on Java 17? Which plugins are known to require a 4.x‑compatible artifact? How can a team verify plugin compatibility before upgrading the maven-wrapper distributionUrl?
32775 reputation · 03 May 2020, 03:42 UTC
Yes — with one caveat. Maven's runtime JDK and the JDK that compiles your sources are independent. Maven 4.0.0 requires Java 17 or newer to start, but maven-compiler-plugin can select a JDK 8 toolchain from toolchains.xml and run that JDK's javac, producing Java 8 bytecode from a Maven process hosted on Java 17. The caveat: toolchains only affect toolchain-aware plugins (compiler, javadoc, surefire when it forks). The compiler plugin's own code, like every other plugin, executes inside Maven's Java 17 JVM — so plugin compatibility is a separate problem from the compilation target.
Because 4.0.0 is a new major release, treat the specifics below as a conservative draft: confirm them against the 4.0.0 release notes before standardizing.
mvn -version under Maven 4 reports the Java 17 runtime no matter what toolchains declare.<source>1.8</source><target>1.8</target> — --release is a JDK 9+ javac option. Conversely, if Java 8 bytecode is the only goal, a JDK 17 toolchain with <release>8</release> also emits major version 52 output and removes the need to install JDK 8 on CI at all.# ~/.m2/toolchains.xml (minimal JDK 8 entry)
<toolchains>
<toolchain>
<type>jdk</type>
<provides><version>8</version></provides>
<configuration><jdkHome>/opt/jdk8</jdkHome></configuration>
</toolchain>
</toolchains>There is no authoritative list I can give you; compatibility has to be verified per plugin and per version. The reliable generalizations: plugins run inside Maven's JVM, so any plugin calling JDK-internal APIs removed after Java 8/11 fails at runtime regardless of the declared toolchain. Plugins built against the Maven 3 plugin API generally still load, but Maven 4 dropped long-deprecated surfaces (maven-compat, legacy artifact resolution), so very old plugin versions and in-house mojos compiled against those APIs are the likely breakage points. Anything more specific should come from running your own build, not from a list.
mvn -Dmaven.plugin.validation=VERBOSE validate. The 3.9 line flags plugins that may be incompatible with Maven 4. (Confirm the flag against your version's documentation.)javap -v target/classes/YourClass.class | grep major should print major version 52..mvn/wrapper/maven-wrapper.properties.The wrapper is the sharp edge: distributionUrl is pinned per project, so switching it to a 4.x URL changes every developer and CI run simultaneously. CI images providing only Java 8 or 11 fail at Maven startup — typically an UnsupportedClassVersionError citing class file version 61.0 — before any toolchain logic runs. Maven 3.9.x remains a safe fallback while those images are updated.
If your build pins old plugin versions or contains in-house mojos, share which ones. That determines whether the validation pass is a formality or a migration project — and whether the JDK 17 plus --release 8 route (no JDK 8 on CI) is the simpler fix.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.