ascheman opened a new pull request, #12771:
URL: https://github.com/apache/maven/pull/12771

   Fixes #12770.
   
   When a plugin has no version anywhere in the effective model, 
`DefaultPluginVersionResolver`
   takes the `RELEASE` version from repository metadata. In Maven's version 
semantics a
   `4.0.0-beta-N` *is* a release, so any plugin whose newest published version 
is a pre-release
   becomes a trap for every build that does not pin:
   
   ```
   $ mvn source:jar                       # Apache Maven 4.0.0-rc-6, no version 
pinned anywhere
   [INFO] --- source:4.0.0-beta-1:jar (default-cli) @ demo ---
   [ERROR] Failed to execute goal 
org.apache.maven.plugins:maven-source-plugin:4.0.0-beta-1:jar …
           java.lang.NoSuchMethodError: 'java.util.List
           org.apache.maven.api.services.ProjectManager.getCompileSourceRoots(
           org.apache.maven.api.Project, org.apache.maven.api.ProjectScope)'
   ```
   
   `maven-source-plugin` currently publishes `<release>4.0.0-beta-1</release>` 
on Central, and that
   beta was built against a Maven 4 API that changed before the line stabilised.
   
   The existing compatibility check does not catch this — the beta's declared 
prerequisites are
   satisfied (it *is* Maven 4), it is only compiled against an API that moved. 
Maven 3 escapes this
   particular case by accident, because there the same prerequisites fail; with 
a pre-release that
   *is* compatible, 3.9.16 selects it just as readily.
   
   #### Change
   
   Prefer a stable version whenever the repository offers one; fall back to 
pre-releases, and then
   to snapshots, only when it does not — so a plugin that has only ever 
published pre-releases still
   resolves.
   
   A pre-release is recognised through the version scheme itself rather than a 
list of qualifier
   names: such a qualifier sorts *before* the version it qualifies (`1.0-beta-1 
< 1.0`), while a
   build or vendor qualifier does not (`1.0-jre > 1.0`).
   
   #### Integration test
   
   `MavenITghUnversionedPluginPrereleaseTest` stages its own plugin repository 
— stable `1.0`,
   pre-release `2.0-beta-1`, metadata naming the pre-release as `<release>` — 
so it keeps testing the
   behaviour after Central's `maven-source-plugin` metadata moves on.
   
   | distribution | result |
   |---|---|
   | this branch | IT passes; full core IT suite green locally (1052 tests, 0 
failures) |
   | master without the fix | IT fails: `Expected file was not found: 
target/touch-stable.txt` |
   
   The full workflow of this repository also passes on a fork of this branch — 
`full-build` and
   `integration-tests` on ubuntu/macos/windows × JDK 17, 21 and 25, all green:
   https://github.com/aschemaven/maven/actions/runs/32263655600
   
   A standalone reproducer with public CI is at
   https://github.com/aschemaven/maven4-unversioned-plugin-pick — the 
`4.0.0-rc-6` job is red, the
   `3.9.16` and `3.10.0-rc-1` jobs are green, and a fourth job shows that 
pinning any concrete 3.x
   version is the workaround.
   
   #### Backport
   
   A `maven-4.0.x` backport is prepared and will follow once this lands 
(`DefaultPluginVersionResolver`
   is identical on both lines). It carries one extra commit adapting the IT to 
that line's older test
   harness — a version-range constructor and a `TestSuiteOrdering` entry, 
neither of which exists on
   master since #11251.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to