Skip to content

Enable Maven 4 build#3352

Open
Bukama wants to merge 2 commits into
apache:masterfrom
Bukama:enableMaven4
Open

Enable Maven 4 build#3352
Bukama wants to merge 2 commits into
apache:masterfrom
Bukama:enableMaven4

Conversation

@Bukama

@Bukama Bukama commented May 12, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@Bukama

Bukama commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

Fails already at

"Surefire Extensions API .............................................................................. FAILURE [ 3.564 s]"

[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.602 s <<< FAILURE! -- in org.apache.maven.plugin.surefire.extensions.CommandlineExecutorTest
[ERROR] org.apache.maven.plugin.surefire.extensions.CommandlineExecutorTest.shouldExecuteNativeCommand -- Time elapsed: 0.583 s <<< FAILURE!
Wanted but not invoked:
eventHandler.handleEvent(contains("a.txt"));
-> at org.apache.maven.plugin.surefire.extensions.CommandlineExecutorTest.shouldExecuteNativeCommand(CommandlineExecutorTest.java:93)
Actually, there were zero interactions with this mock.

        at org.apache.maven.plugin.surefire.extensions.CommandlineExecutorTest.shouldExecuteNativeCommand(CommandlineExecutorTest.java:93)
        at java.base/java.lang.reflect.Method.invoke(Method.java:565)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:511)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1450)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2019)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:187)

@hboutemy

Copy link
Copy Markdown
Member

@ascheman is it the issue you worked on with apache/maven#11983 ?

@ascheman

Copy link
Copy Markdown

@ascheman is it the issue you worked on with apache/maven#11983 ?

Yes, exactly, therefore its just a draft: It depends on a new Maven 4 RC with that change.

@ascheman

ascheman commented May 13, 2026

Copy link
Copy Markdown

Sorry, I see it was drafted by @Bukama, but had a similar draft on my mind and thought, I had already prepared it. As I cannot see the full error trace, I cannot say whether it is exactly the same issue. Nevertheless, Surefire ITs will hardly work with Maven 4 unless the mentioned CLI issue is resolved.

@Bukama

Bukama commented May 18, 2026

Copy link
Copy Markdown
Contributor Author

Note: This PR is for checking build status for Maven 4.0.0 according to checklist https://cwiki.apache.org/confluence/display/MAVEN/Maven+4.0.0+GA+checklist

@Bukama

Bukama commented Jun 13, 2026

Copy link
Copy Markdown
Contributor Author

With current 4.0.0 SNAPSHOT it still fails

Apache Maven 4.0.0-SNAPSHOT (8bedea9479918bdac71455635f0c51a2b5730f05)
Maven home: C:\apache-maven-4.0.x-self
Java version: 25.0.2, vendor: Azul Systems, Inc., runtime: C:\Program Files\Zulu\zulu-25
Default locale: de_DE, platform encoding: UTF-8, time zone: Europe/Berlin
OS name: "windows 11", version: "10.0", arch: "amd64", family: "winnt"
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.543 s <<< FAILURE! -- in org.apache.maven.plugin.surefire.extensions.CommandlineExecutorTest
[ERROR] org.apache.maven.plugin.surefire.extensions.CommandlineExecutorTest.shouldExecuteNativeCommand -- Time elapsed: 0.526 s <<< FAILURE!
Wanted but not invoked:
eventHandler.handleEvent(contains("a.txt"));
-> at org.apache.maven.plugin.surefire.extensions.CommandlineExecutorTest.shouldExecuteNativeCommand(CommandlineExecutorTest.java:93)
Actually, there were zero interactions with this mock.

        at org.apache.maven.plugin.surefire.extensions.CommandlineExecutorTest.shouldExecuteNativeCommand(CommandlineExecutorTest.java:93)
        at java.base/java.lang.reflect.Method.invoke(Method.java:565)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:511)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1450)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2019)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:187)

[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR]   CommandlineExecutorTest.shouldExecuteNativeCommand:93
Wanted but not invoked:
eventHandler.handleEvent(contains("a.txt"));
-> at org.apache.maven.plugin.surefire.extensions.CommandlineExecutorTest.shouldExecuteNativeCommand(CommandlineExecutorTest.java:93)
Actually, there were zero interactions with this mock.

[INFO]
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
[INFO]
[INFO] --------------------------------------------------------------------------------------------------------------------------
[INFO] Reactor Summary for Apache Maven Surefire 3.6.0-M2-SNAPSHOT:
[INFO]
[INFO] Apache Maven Surefire ................................................................................ SUCCESS [  4.213 s]
[INFO] Surefire Shared Utils ................................................................................ SUCCESS [  1.784 s]
[INFO] Surefire Logger API .................................................................................. SUCCESS [  4.247 s]
[INFO] Surefire API ......................................................................................... SUCCESS [ 15.399 s]
[INFO] Surefire Extensions API .............................................................................. FAILURE [  3.130 s]
[INFO] Surefire Extensions SPI .............................................................................. SKIPPED

@ascheman

Copy link
Copy Markdown

Hey @Bukama — looking at the latest CI matrix on this PR and pulling apart the failure patterns:

JDK 11 cells (fast-fail, ~40s): all three OS × JDK 11 × 4.0.0-rc-5 cells die at startup with Apache Maven 4.x requires Java 17 or newer to run. Maven 4 dropped JDK 11 support, so those matrix cells need to be excluded from the Maven 4 lane. A small matrix-exclude entry in .github/workflows/maven.yml should fix this — something like:

matrix-exclude: '[
  { "jdk": "11", "maven": "4.0.0-rc-5" }
]'

(Other plugin enablement PRs use the same pattern.)

JDK 17 / 21 cells (late-fail, ~10–15min): all six fail with the same root cause:

java.lang.NoSuchMethodException:
  org.apache.maven.cling.MavenCling.doMain(
    [Ljava/lang/String;, java/lang/String, java/io/PrintStream, java/io/PrintStream)

This is maven-shared-verifier ↔ Maven 4 API drift, not a surefire issue. The verifier's reflection call against MavenCling.doMain(...) uses a 4-argument signature that Maven 4 rc-5 has changed (likely PrintStreamOutputStream or similar). Every IT that launches a Maven sub-build fails identically.

This won't go away with a workflow flip — it needs either a maven-shared-verifier release that handles both signatures, or a surefire-side change to invoke Maven through a different launcher path.

Happy to look into the verifier side and report back. I'll follow up once I have a concrete fix path or a clearer upstream owner.

Enable Maven 4 in the CI matrix by setting maven4-enabled: true.
Exclude JDK 11 from Maven 4 cells since Maven 4 requires Java 17+
(JDK 8 is already auto-excluded by the shared workflow).

Force forked JVM mode in MavenLauncher when Maven 4 is detected,
working around maven-verifier 2.0.0-M1's broken embedded-mode
reflection against the changed MavenCling.doMain() signature in
Maven 4 rc-5. Detection checks for maven-cling-*.jar in the
Maven home lib directory. This workaround can be removed once
surefire migrates from maven-verifier to maven-executor.

Also fix a pre-existing race condition in CountdownCloseable where
awaitClosed() used 'if' instead of 'while' to guard Object.wait(),
making it vulnerable to spurious wakeups per the JLS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet

gnodet commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

I force-pushed with a rebased commit on top of current master that addresses all three failure categories from the CI runs:

1. Matrix exclusion fix

The original exclude used "maven": "4" but the shared workflow expands the matrix with the exact version string "4.0.0-rc-5", so the JDK 11 cells were never excluded. Fixed to "maven": "4.0.0-rc-5". The JDK 8 exclude was also removed since the shared workflow already auto-excludes JDK 8 when maven4-enabled=true.

2. IT failures — force forked mode for Maven 4

All integration tests failed because maven-verifier:2.0.0-M1 uses reflection to call MavenCling.doMain(String[], String, PrintStream, PrintStream) in embedded mode, but Maven 4 rc-5 changed this method signature. The fix adds an isMaven4() detection in MavenLauncher that checks for maven-cling-*.jar in $MAVEN_HOME/lib/ and forces forkJvm=true, bypassing the broken reflection entirely.

This is a short-term workaround. The long-term fix is to migrate from maven-verifier (which is being deprecated) to maven-executor (org.apache.maven.executor:maven-executor:1.0.0), which natively supports both Maven 3.x and 4.x.

3. CountdownCloseable race condition (bonus fix)

CountdownCloseable.awaitClosed() used if instead of while to guard Object.wait(), making it vulnerable to spurious wakeups per the JLS. This is a pre-existing bug that could explain the intermittent CommandlineExecutorTest failures reported on Windows — the test itself passes fine in CI on all platforms with both Maven 3 and 4.

The Maven 4 distribution does not contain a separate maven-cling
jar. The MavenCling class is inside maven-cli-4.x.jar, which is
a Maven 4-only artifact not present in Maven 3.x distributions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gnodet

gnodet commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

CI Analysis — Maven 4 IT Failures

All Maven 3 cells pass ✅ across all OS/JDK combinations.

The Maven 4 cells show ~56 failing ITs out of 751 (~92.5% pass rate). Analysis of the failures:

Exit Code 2 Failures (20 tests)

Affected: ForkCountIT (8), ForkCountMultiModuleIT (4), ForkCountTestNGIT (8)

Root cause: A known bug in Maven 4.0.0-rc-5's bin/mvn script. The rc-5 script uses eval exec "$cmd" which interprets ${...} patterns as shell variables. These tests pass -DtestProperty=testValue_${surefire.threadNumber}_${surefire.forkNumber} as a CLI argument. On dash (Ubuntu's /bin/sh), dots in variable names trigger Bad substitution → exit code 2.

Status: Already fixed in Maven's main branch (e6a9c4216b, 2026-05-19) and 4.0.x branch (8f7bdee4c4, 2026-05-20), but not yet released.

Not fixable in surefire — the bug is in Maven's launcher script.

Other Maven 4 Failures (~36 tests)

Genuine Maven 4 behavioral differences:

  • FailFastJUnit4IT (7): Reports directory is missing — Maven 4 build completes but surefire-reports directory not generated
  • RunOrderIT / RunOrderParallelForksIT (14): Test execution order assertions fail — Maven 4 may handle run ordering differently
  • Various Surefire*IT (~15): Assertion failures on test counts, missing log text, classloader differences

These are separate Maven 4 compatibility issues that need follow-up investigation.

Summary

Category Tests Fixable Here?
Maven 3 (all cells) ✅ All pass
Maven 4 exit code 2 20 failures ❌ Maven script bug (fixed in unreleased main)
Maven 4 behavioral ~36 failures ❌ Need separate follow-up PRs
Maven 4 passing ~695 passing

The isMaven4() detection + forked mode workaround resolved the original NoSuchMethodException from maven-verifier 2.0.0-M1's incompatible embedded mode. The remaining failures are inherent Maven 4 compatibility gaps that can be tracked separately.

@gnodet
gnodet marked this pull request as ready for review July 25, 2026 06:44
@gnodet

gnodet commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Local Verification with Maven 4.0.x SNAPSHOT

Built Maven from the maven-4.0.x branch (which includes the mvn script fix) and ran the 20 tests that fail with exit code 2 on rc-5:

Test Class rc-5 4.0.x SNAPSHOT
ForkCountIT (8 tests) ❌ exit code 2 ✅ 8/8 pass
ForkCountMultiModuleIT (4 tests) ❌ exit code 2 ✅ 4/4 pass
ForkCountTestNGIT (8 tests) ❌ exit code 2 ✅ 8/8 pass

All 20 exit-code-2 failures are resolved. These will pass automatically in CI once rc-6 ships — no surefire changes needed for this category.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants