slachiewicz commented on issue #13302:
URL: https://github.com/apache/maven/issues/13302#issuecomment-5919281733

   ### Wave 3 findings
   
   maven-build-cache-extension has its own comment above. Each port is a local 
branch `agent/mvn4-api`; the PRs are not opened yet.
   
   #### Migration not needed
   
   No Maven API in the library modules, so only CI changes (branch 
`agent/mvn4-api`, one commit "Build with Maven 4 only"; PRs not opened yet). 
Verified locally with `mvn verify`, Maven 4.0.0-rc-7, JDK 21:
   
   - maven-jxr: 34 tests, 0 failures (only maven-jxr-plugin uses the Maven API).
   - maven-wrapper: 34 tests, 0 failures (only maven-wrapper-plugin uses the 
Maven API).
   - maven-archetypes: 18 archetype builds, 0 failures (only the archetype 
templates use the Maven API).
   - maven-wagon: 1035 tests, 0 failures, 10 skipped.
   - maven-executor: 62 tests, 0 failures, 4 skipped.
   - maven-scm: 340 tests, 0 failures, 3 skipped (only maven-scm-plugin uses 
the Maven API).
   
   #### Ported libraries
   
   <details><summary><b>maven-surefire</b>: partial</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **partial**, 
4.0.0-SNAPSHOT, Java 17 (maven-surefire-common only).
   
   Verified locally: `mvn verify` with Maven 4.0.0-rc-7, JDK 21 → before: 1487 
tests in 12 modules, 0 failures (maven-surefire-common 867); after: 
maven-surefire-common 868 (865 with `E2ETest` excluded, 0 failures), other 
library modules unchanged. `E2ETest.endToEndTest` times out under machine load 
on the unmodified tree too (36 s against 30 s). maven-surefire-plugin, 
maven-failsafe-plugin and surefire-its are out of the reactor, so their 35 unit 
tests and all ITs did not run after. Spotless and RAT clean.
   
   **Only maven-surefire-common uses the Maven API.** surefire-booter, -api, 
-extensions-api, -logger-api, -report-parser and the providers import none; 
they run in the forked test JVM, stay on `release 8`, and need no port.
   
   **Public API changes** (maven-surefire-common)
   - `AbstractSurefireMojo` implements `org.apache.maven.api.plugin.Mojo`; 
`getSession()`, `getProject()`, `getToolchainManager()` return v4 types; 
`MojoFailureException`/`MojoExecutionException` both become the unchecked 
`MojoException`.
   - `getPluginDescriptor()` removed; 
`getPluginArtifactMap()`/`getProjectArtifactMap()` return v4 artifacts, 
computed lazily.
   - `SurefireDependencyResolver` takes a `Session`; `isWithinVersionSpec` is 
no longer static.
   - Parameter `additionalClasspathDependencies` becomes 
`List<AdditionalClasspathDependency>`, a new bean with the same XML, because 
the immutable v4 model cannot be populated from configuration.
   - DI moves to `org.apache.maven.api.di`; Sisu no longer discovers 
`ProviderDetector` or `SurefireDependencyResolver`.
   
   **Gaps**
   - The library holds the mojo base class, so `SurefireMojo` and 
`IntegrationTestMojo` cannot stay on Maven 3 while it moves: library and 
plugins must be ported together.
   - No `MavenExecutionRequest` in the API: `-e` and `-ff`/`-fae`/`-fn` no 
longer reach the forked JVM.
   - No v4 counterpart for `${plugin.artifactMap}`, `${project.artifactMap}`, 
`${plugin}`, `${basedir}`, `${session.parallel}`.
   - No static version parser: `Session.parseVersionRange` needs a session.
   - No `ArtifactHandler`: `isAddedToClasspath()` becomes 
`!Type.getPathTypes().isEmpty()`.
   - `ScopeArtifactFilter` differs: with `classpathDependencyScopeExclude` = 
`provided` or `system`, the v3 filter excludes nothing and the v4 one excludes 
that scope.
   - `LocationManager` (plexus-java) is a Sisu component; created with `new`.
   - Depends on the unreleased maven-common-artifact-filters 4.0.0-SNAPSHOT 
(apache/maven-common-artifact-filters#130).
   
   **Consumers that break:** maven-surefire-plugin, maven-failsafe-plugin, 
surefire-its in this repository. Outside it, only the maven-plugin-plugin 
`mplugin-305_*` ITs extend `AbstractSurefireMojo`, and they pin 3.1.0.
   
   **Improvements:** maven-surefire-common drops maven-core, maven-plugin-api, 
maven-artifact, maven-model, maven-resolver-api/-util, `javax.inject`, 
`org.eclipse.sisu.plexus`.
   
   **Recommendation:** port the library only together with 
maven-surefire-plugin and maven-failsafe-plugin, and keep a 3.x line. The API 
first needs the request flags on `Session`, a session-free version parser, and 
test fixtures for `Dependency` and `Project`.
   
   </details>
   
   <details><summary><b>maven-release</b>: partial</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **partial**, 
4.0.0-SNAPSHOT, Java 17. The library modules (`maven-release-api`, 
`maven-release-manager`, both policies) compile against `org.apache.maven.api` 
only and pass; the plugin is a consumer and is excluded. The immutable model 
forced a redesign of the POM-rewriting layer, and plugin/extension/report 
artifact resolution is reduced.
   
   Verified locally: `mvn verify` with Maven 4.0.0-rc-7, JDK 21 → before 876 
tests (api 0, manager 769, odd-even 11, semver 78, plugin 18), 0 failures, 18 
skipped (manager); after 791 (api 0, manager 700, odd-even 12, semver 79), 0 
failures, same 18 skipped. Spotless and checkstyle clean. The manager lost 88 
tests and gained 19 (net -69). The 88 are the tests of the removed Maven 3 
model subclasses, almost all asserting `UnsupportedOperationException` for 
methods that no longer exist: `DomTripDependencyTest` 24, `DomTripParentTest` 
11, `DomTripExtensionTest` 10, `DomTripDependencyManagementTest` 6, and 37 of 
the 45 in `DomTripBuildTest`. The behaviour that was real (get/set version, 
group and artifact id, element name) is covered by the 10 tests of 
`DomTripMavenCoordinateTest`; the parent test that added or removed a missing 
`<version>` element is not carried over. The other 9 new tests are 3 in 
`DomTripBuildTest`, 5 in `DependencyInjectionTest` and 1 `DiIndexTest` (plus 
one `DiInd
 exTest` in each policy module). The plugin's 18 unit tests and the `run-its` 
profile (it lives in the plugin module) were not run, before or after: the 
plugin does not compile against the ported libraries, so there is no "after".
   
   **Public API changes**
   - `ReleasePhase.execute/simulate`, `ResourceGenerator.clean`, 
`Release*Request.get/setReactorProjects`: `List<MavenProject>` → 
`List<org.apache.maven.api.Project>`.
   - `ReleaseEnvironment.getSettings()` returns 
`org.apache.maven.api.settings.Settings`; new `Session getSession()` (phases 
need it for `collectDependencies` and the XML factories), 
`DefaultReleaseEnvironment.setSession`.
   - `ReleaseDescriptor.getOriginalScmInfo`, 
`ReleaseDescriptorBuilder.addOriginalScmInfo` and the modello-generated 
descriptor: `org.apache.maven.model.Scm` → `org.apache.maven.api.model.Scm`. 
`IdentifiedScm` is immutable: `new IdentifiedScm(Scm, id)`, no setters (the v4 
`Scm` has a protected builder constructor, so it can still be subclassed).
   - `VersionPolicyRequest.get/setMetaData`: 
`artifact.repository.metadata.Metadata` → 
`org.apache.maven.api.metadata.Metadata`.
   - `Version.compareTo` no longer throws `VersionComparisonConflictException` 
(one ordering instead of two; the class stays, never thrown). New 
`versions.ArtifactKeys` (`versionlessKey`, `isSnapshot`, `SNAPSHOT_VERSION`, 
`VERSION_FILE_PATTERN`) replaces `ArtifactUtils`.
   - `DefaultReleaseManagerListener(Log)` → `(org.slf4j.Logger)`; the API has 
no `Log`.
   - `ModelETL.getModel()` returns the new `PomModel`; 
`ModelETLRequest.setProject(Project)`; `AbstractRewritePomsPhase.transformScm` 
takes `(Project, PomModel, Model originalModel, ...)`. 
`DomTripDependency/Extension/Parent/DependencyManagement/PluginManagement/Reporting/ReportPlugin`
 are gone; the other DomTrip classes implement the new `PomModel`, `PomBuild`, 
`PomPlugin`, `PomProfile`, `PomScm` views instead of subclassing Maven 3 model 
classes.
   - `ScmRepositoryConfigurator.getConfiguredRepository(..., Settings)` takes 
the v4 `Settings`. `AbstractMavenExecutor`, `ForkedMavenExecutor`, 
`InvokerMavenExecutor` take a `SettingsXmlFactory`; `getSettingsWriter()` → 
`getSettingsXmlFactory()`. `PomFinder(Logger, ModelXmlFactory)`. 
`GenerateReleasePomsPhase` takes a `ModelXmlFactory` instead of 
`ModelInterpolator`. `MavenCrypto(SecDispatcher)` on plexus-sec-dispatcher 
4.2.0.
   - `@Named`/`@Singleton`/`@Inject` move to `org.apache.maven.api.di`, 
`@Description` is dropped; Sisu no longer discovers any component. 
`DefaultStrategy`, `DefaultVersionPolicy`, `DefaultNamingPolicy` become 
`@Named("default")` (see traps below).
   
   **Design changes forced by the immutable model**
   - The DomTrip layer was `DomTripModel extends Model` plus a dozen subclasses 
of Maven 3 model classes, overriding the setters they needed and throwing 
`UnsupportedOperationException` for the rest. The v4 `Model` cannot be edited 
in place, so the rewrite phases now edit the DOM through five small `Pom*` 
views (`setVersion`, `setScm`, coordinate `setVersion`, `Properties`). This is 
a redesign, not a port: the `transform` package goes from 2151 to 1598 lines, 
including the new interfaces.
   - `GenerateReleasePomsPhase` built the release POM by cloning the 
`MavenProject` and calling setters; it now derives the release model with 
`Model.newBuilder(effective, true)`.
   
   **Gaps**
   - `MavenProject.getOriginalModel()` (9 uses) has no equivalent. The original 
model is read again from the POM file with `ModelXmlFactory`. Consequence: 
`generate-release-poms` runs after `rewrite-poms-for-release`, so it now reads 
plugin, extension and plugin-dependency declarations that are already 
rewritten; Maven 3 kept the load-time snapshot.
   - No plugin, extension or report artifact API and no `RELEASE`/`LATEST` 
resolution 
(`MavenProject.getPluginArtifacts/getReportArtifacts/getExtensionArtifacts` and 
their maps). Versions come from the effective model. A plugin, report plugin or 
extension without a version stays without one in the release POM (Maven 3 wrote 
the resolved version; one expected file had `<version>RELEASE</version>` and 
was changed), and `CheckDependencySnapshotsPhase` cannot see a snapshot behind 
it.
   - `Session.collectDependencies(project, TEST_COMPILE ∪ TEST_RUNTIME)` 
replaces `getArtifacts/getDependencyArtifacts`. It throws when any dependency 
POM cannot be read, where Maven 3 still listed the declared artifact; the code 
falls back to the declared coordinates and an empty transitive set.
   - `MavenProject.getParentArtifact()`: only `Project.getParent()`, present 
when the parent project was built.
   - No `ModelInterpolator`. The super POM path unaligning in 
`GenerateReleasePomsPhase` uses plexus-interpolation over the v4 model (kept as 
a dependency).
   - `api.Version` needs a `VersionParser` service, but `Version` and 
`DefaultVersionInfo` are plain value classes. They use the resolver's 
`GenericVersionScheme` (new direct dependency `maven-resolver-util`); the 
`ComparableVersion` cross-check is dropped.
   - No crypto API. `MavenCrypto` uses plexus-sec-dispatcher 4.2.0, whose 
legacy dispatcher can only decrypt. `encryptSettings` needs a v4 `master` 
dispatcher configuration; without one the passwords go unencrypted into the 
temporary `settings.xml` for the forked build (the failure was already 
swallowed in Maven 3).
   - `maven-scm-manager-plexus` gets its providers through Sisu map injection, 
which the v4 container does not do. `ReleaseScmManager` reads 
`META-INF/sisu/javax.inject.Named` itself and instantiates the providers that 
have a public no-argument constructor.
   - The parent sets `<proc>none</proc>`, so 
`META-INF/maven/org.apache.maven.api.di.Inject` is maintained by hand in all 
three modules; `DiIndexTest` fails when a `@Named` class is missing (checked by 
removing `DefaultStrategy`).
   - Not verified: injection of `Prompter` and `SecDispatcher` in a real Maven 
4 plugin container. `ApiRunner.createSession` binds neither, so the tests bind 
them. No release was run end to end.
   - Traps: a bare `@Named` is the empty key in `Map<String, T>` injection, not 
`default` as in Sisu (`Policy 'default' is unknown, available: []`); 
`model.with().parent(null).build()` does not clear the parent (null is ignored 
on a builder from `with()`; use `withParent(null)` or `Model.newBuilder(model, 
true)`); `DependencyResolver.collect` needs a `ProjectManager` service that 
only maven-core provides.
   - Release POM content changes with the v4 effective model: no 
`repositories`/`pluginRepositories` (the central declarations are no longer in 
the model) and three extra properties (`project.build.outputTimestamp`, 
`project.build.sourceEncoding`, `project.reporting.outputEncoding`). 58 
expected files under `src/test/resources/projects/generate-release-poms` were 
adjusted for this.
   - Tests: there is no project builder outside maven-core. The harness builds 
`TestProject` from the `ModelBuilder` of maven-impl and resolves against a 
local repository seeded from `src/test/remote-repository` (marked `>central=`), 
with a stub `ProjectManager`. It uses `DefaultDependencyCoordinates` and 
`InternalSession` from maven-impl, which are internal classes.
   
   **Consumers that break:** maven-release-plugin (same repository): 15 compile 
errors in 8 classes, measured by compiling its sources against the ported jars. 
`AbstractReleaseMojo:131` (`setSettings` takes the Maven 3 `Settings`); 
`CleanReleaseMojo`, `RollbackReleaseMojo`, `PrepareReleaseMojo`, 
`BranchReleaseMojo`, `PerformReleaseMojo`, `UpdateVersionsMojo` 
(`setReactorProjects(getReactorProjects())` with `List<MavenProject>`, and `new 
DefaultReleaseManagerListener(getLog())` with `Log`); 
`AbstractScmReadReleaseMojo:145` and `UpdateVersionsMojo:124` 
(`addOriginalScmInfo` with the Maven 3 `Scm`). At runtime its `@Inject 
ReleaseManager` and `ScmManager` would also find no Sisu components. 
maven-scm-publish-plugin, by reading: `AbstractScmPublishMojo:352` passes a 
Maven 3 `Settings` to `getConfiguredRepository`, and it injects 
`ScmRepositoryConfigurator` with `javax.inject`. No other repository under the 
Apache Maven plugin repositories imports `org.apache.maven.shared.release`.
   
   **Improvements:** drops `maven-core`, `maven-model`, `maven-model-builder`, 
`maven-artifact`, `maven-settings`, `maven-plugin-api`, 
`maven-repository-metadata`, `plexus-interactivity-api`, `plexus-cipher`, 
`plexus-sec-dispatcher` 2.0 (it clashed by coordinates with the 4.2.0 that 
maven-impl brings), `maven-scm-manager-plexus`, `javax.inject`, 
`org.eclipse.sisu.inject`, `sisu-maven-plugin`, and the test-only 
`plexus-testing`, `org.eclipse.sisu.plexus` and four resolver modules.
   
   **Recommendation:** port the libraries for a Maven 4 release plugin, but 
only together with a Maven 4 port of the plugin. The API first needs a way to 
resolve plugin and extension versions and an original (file) model on 
`Project`; without them the release POM and the snapshot check are weaker than 
on 3.x. Keep the 3.x line for Maven 3 builds.
   
   </details>
   
   <details><summary><b>maven-enforcer</b>: partial</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **partial**, 
4.0.0-SNAPSHOT, Java 17. `enforcer-api` and `enforcer-rules` ported; 3 of 38 
rules removed for lack of API; `maven-enforcer-plugin` and 
`maven-enforcer-extension` excluded from the reactor.
   
   Verified locally: `mvn verify` with Maven 4.0.0-rc-7, JDK 21 → before 300 
tests (rules 276, plugin 24), 0 failures; after, library modules only: rules 
347 (272 ported, 75 new), 0 failures. Spotless, checkstyle and RAT clean. ITs 
(154 invoker projects in the plugin module) cannot run after, because the 
plugin no longer builds. Removed tests: the 3 of the removed rules and 1 of a 
test-only `PluginParameterExpressionEvaluator` subclass.
   
   **Public API changes**
   - `enforcer-api`, the SPI third-party rules implement: 
`AbstractEnforcerRuleConfigProvider.getRulesConfig()` returns 
`org.apache.maven.api.xml.XmlNode` instead of `Xpp3Dom`. The deprecated 
`EnforcerRule`, `EnforcerRule2` and `EnforcerRuleHelper` are removed; they 
expose `PlexusContainer` and the Maven 3 `Log`. `AbstractEnforcerRule`, 
`EnforcerRuleBase`, `EnforcerLogger`, `EnforcerLevel`, `EnforcerRuleException`, 
`EnforcerRuleError` are unchanged.
   - `enforcer-rules`: DI moves to `org.apache.maven.api.di`, so Sisu finds no 
rule. Rules take `Project`, `Session`, `ProjectManager`, `VersionParser` 
instead of `MavenProject`, `MavenSession`, `RuntimeInformation`, 
`PluginManager`, `RepositorySystem`.
   - `utils.ExpressionEvaluator` no longer extends 
`PluginParameterExpressionEvaluator`; `${mojo.*}`, `${plugin.*}`, 
`${localRepository}` are not supported.
   - Removed rules: `requireUpperBoundDeps`, `banDynamicVersions`, 
`requireProfileIdsExist`.
   
   **Gaps**
   - `Node` has no pre-managed version and no declared version constraint. 
`requireUpperBoundDeps` compares the pre-managed version and 
`banDynamicVersions` checks ranges and `LATEST`/`RELEASE` of transitive 
dependencies; a port would silently narrow both, so they are removed.
   - `Session` has no requested (`-P`) profile ids: `requireProfileIdsExist` is 
removed.
   - No original model on `Project`: five rules re-parse `pom.xml` through 
`ModelXmlFactory`.
   - No resolved-artifact view of a project: `requireSameVersions`, 
`bannedDependencies`/`requireReleaseDeps` (`searchTransitive=false`) and 
`enforceBytecodeVersion` now run a resolution request.
   - No public `ProfileActivationContext` or no-op `ModelProblemCollector`: 
`requireOS` carries hand-written implementations.
   - `requirePluginVersions` is tested against mocks only; its check for 
versions from the default lifecycle bindings is not verified on Maven 4.
   - Rule configuration from `<rules>` (Plexus `ComponentConfigurator` from 
`Xpp3Dom`) has no API equivalent; it belongs to the plugin port. Nothing ran 
end to end in a real Maven 4 build.
   
   **Consumers that break**
   - maven-enforcer-plugin (`EnforceMojo`, `DisplayInfoMojo`, 
`DefaultEnforcementRuleHelper`, `EnforcerRuleCache`) and 
maven-enforcer-extension (`AbstractMavenLifecycleParticipant`), both in this 
repository.
   - mojohaus/extra-enforcer-rules: its 9 rules still compile against the 
unchanged SPI types, but inject `MavenProject`/`MavenSession` through 
`javax.inject`, so Maven 4 DI does not find them; it has to move with the 
plugin.
   - Any third-party rule implementing `EnforcerRule`/`EnforcerRule2` or 
calling `EnforcerRuleHelper.getComponent`.
   
   **Improvements:** `enforcer-api` drops everything but `maven-api-xml`; 
`enforcer-rules` drops maven-core, maven-artifact, maven-plugin-api, 
maven-model(-builder), maven-settings, maven-resolver-api/-util, 
`javax.inject`, `org.eclipse.sisu.plexus`, plexus-utils, plexus-xml.
   
   **Recommendation:** do not release. The rules are usable only once 
maven-enforcer-plugin can configure and look up v4 rules, which is the larger 
half. Ask apache/maven for a pre-managed version and declared constraint on 
`Node` and requested profile ids on `Session` before dropping the 3 rules for 
good. Keep a 3.x line for Maven 3 and for extra-enforcer-rules.
   
   </details>
   
   <details><summary><b>maven-plugin-tools</b>: partial</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **partial**, 
5.0.0-SNAPSHOT, Java 17.
   
   Verified locally: `mvn verify -P run-its` with Maven 4.0.0-rc-7, JDK 21, 
library modules → api 61 unit + 15 IT before and after; generators 17 (1 
skipped) before and after; annotations 37 before, 42 after (new: DI wiring, 
sources-jar resolution); 0 failures. Spotless clean. maven-plugin-plugin (12 
unit, 32 ITs) and maven-plugin-report-plugin (3 unit, 12 ITs) were green before 
and are excluded from the reactor after.
   
   Everything except the descriptor model moves to the Maven 4 API. 
`PluginDescriptor`, `MojoDescriptor` and `Parameter` stay on 
`org.apache.maven.plugin.descriptor` because the tools still write the Maven 3 
`plugin.xml`.
   
   **Public API changes**
   - `PluginToolsRequest`: constructor `(Session, Project, PluginDescriptor)`; 
`getProject()` returns `Project`; `getDependencies()` is 
`Set<org.apache.maven.api.Artifact>`; `getSettings()` is the v4 `Settings`; 
`getRepoSession()`/`setRepoSession()` removed.
   - `PluginUtils.isMavenReport(String, Session, Project)` replaces `(String, 
MavenProject)`; deprecated `GeneratorUtils.isMavenReport` removed; 
`toComponentDependencies` takes v4 `Dependency`.
   - `PluginHelpGenerator`: `setMavenProject(Project)`; `setVelocityComponent` 
→ `setVelocityEngine`.
   - `MojoAnnotationsScannerRequest` takes `Session`, `Project` and v4 
artifacts; `JavadocLinkGenerator`/`JavadocSite` take v4 `Settings`.
   - `@Named`/`@Singleton`/`@Inject` move to `org.apache.maven.api.di`: Sisu no 
longer finds the extractors, scanners or converters, so they cannot be injected 
under Maven 3.
   
   **Gaps** (rc-7)
   - The descriptor model exists (`org.apache.maven.api.plugin.descriptor`, 
`PluginXmlFactory`), but `MojoDescriptor` has no `threadSafe`, 
`instantiationStrategy`, `executionStrategy` or `requiresReports`, `Parameter` 
has no `implementation` or `requirement`, and `PluginDescriptor` has no 
`dependencies`. It cannot carry a Maven 3 `plugin.xml`, so it cannot be the 
tools' internal model. There is also no plugin manager or descriptor lookup 
service.
   - `MavenProject#getArtifacts()` has no `Project` equivalent; 
`Session#resolveDependencies(project, PathScope.MAIN_COMPILE)` returns paths 
only and covers compile and provided scope, not runtime.
   - `MavenProject#getProjectReferences()` has no equivalent; projects are 
matched from `Session#getProjects()` by GAV.
   - No `Dependency` factory outside a resolved graph; no `Version` factory 
outside a `Session`; `Settings` has no `getActiveProxy()`.
   - Plexus components (`ArchiverManager`, `VelocityComponent`) cannot be 
injected through `api.di`; sources jars are unpacked with `java.util.zip` (with 
a zip-slip check), so only `*-sources.jar` is supported.
   - `<proc>none</proc>` in the parent: the DI index files are maintained by 
hand; a new test fails when an entry is missing.
   - `ProjectManager#getEnabledSourceRoots` is stubbed in tests; nothing ran 
the extractors end to end on a real Maven 4 project.
   
   **Consumers that break**
   - maven-plugin-plugin `DescriptorGeneratorMojo`, `HelpGeneratorMojo`; 
maven-plugin-report-plugin `PluginOverviewRenderer`, `GoalRenderer`. Both are 
excluded from the reactor.
   - A Maven 3 plugin build cannot use these libraries at all: Maven 3.9 has no 
`Session`/`Project` API.
   
   **Improvements:** drops maven-core, maven-settings, maven-resolver-api, 
`javax.inject`, `plexus-archiver`, `plexus-velocity`, `sisu-maven-plugin`. 
Still needs maven-plugin-api, maven-model, maven-artifact for the descriptor 
model.
   
   **Recommendation:** do not release a "Maven 4 API" 5.0.0 while the public 
descriptor types are Maven 3. Decide first between a tools-owned descriptor 
model and dropping Maven 3 `plugin.xml` output; keep `maven-plugin-tools-3.x` 
as the line maven-plugin-plugin builds on.
   
   </details>
   
   <details><summary><b>maven-archetype</b>: partial</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **partial**, 
4.0.0-SNAPSHOT, Java 17.
   
   Verified locally: `mvn verify` with Maven 4.0.0-rc-7, JDK 21 → 57 tests 
before (archetype-common 29, maven-archetype-plugin 28), 0 failures; after 30 
in archetype-common (29 ported, 1 new), 0 failures, spotless clean. The plugin 
(28 tests, 33 integration test projects) is a consumer that does not compile 
against the ported library, so it is excluded from the reactor and its tests 
and ITs were not run after. `-Prun-its` before: 20 of 33 IT projects finished 
(all passed) when the 30-minute time box ended. For the code with no unit test 
(`FilesetArchetypeCreator`, POM rewriting) I generated an archetype from a 
3-module fixture with both builds and diffed the output trees: identical apart 
from the version string and a timestamp, with `keepParent` true and false.
   
   **Public API changes** (archetype-common)
   - `ArchetypeGenerationRequest`: `MavenSession`, `RepositorySystemSession`, 
`RepositorySystem`, `ProjectBuildingRequest`, `ArtifactRepository` (local and 
remote) getters and setters are replaced by one 
`getSession()`/`setSession(org.apache.maven.api.Session)`; 
`getRemoteRepositories()` is now `List<org.apache.maven.api.RemoteRepository>`.
   - `ArchetypeCreationRequest.project`: `MavenProject` → 
`org.apache.maven.api.Project`.
   - `ArchetypeManager`, `ArchetypeDataSource`, `Downloader`, 
`ArchetypeArtifactManager`: `RepositorySystemSession` → `Session`, aether 
`RemoteRepository` → API `RemoteRepository`. 
`ArchetypeManager.archiveArchetype` no longer declares 
`DependencyResolutionRequiredException`.
   - `PomManager` reads and writes the immutable 
`org.apache.maven.api.model.Model`. Constructors change: 
`DefaultPomManager(ModelXmlFactory)`, `DefaultOldArchetype(ArchetypeVelocity, 
ArchetypeArtifactManager, ModelXmlFactory)`, `DefaultFilesetArchetypeGenerator` 
takes `ArchetypeVelocity` instead of `VelocityComponent`, 
`DefaultArchetypeGenerator` drops `RepositorySystem`.
   - `plexus-velocity` is gone; the new `ArchetypeVelocity` builds the engine 
with the settings `DefaultVelocityComponent` 2.4.0 applies (read from its 
bytecode) plus the former `VelocityConfigurator` settings. The 
`VelocityComponentConfigurator` extension point is lost.
   - `@Named`/`@Singleton`/`@Inject` move to `org.apache.maven.api.di`; Sisu no 
longer discovers these components, so they cannot be injected under Maven 3.
   
   **Gaps**
   - No metadata resolution in the API. `RemoteCatalogArchetypeDataSource` now 
fetches `archetype-catalog.xml` through `TransportProvider`: no local 
repository cache, update policy or checksum check. The old lookup also matched 
a repository by the id of a repository it mirrors 
(`getMirroredRepositories()`); the API `RemoteRepository` has none, so only ids 
`archetype` and `central` match. Not exercised by a test (none existed).
   - `RepositoryPolicy` cannot be set on a repository created with 
`Session.createRemoteRepository(id, url)`; the `archetypeRepository` URL used 
to get always-update and warn-on-checksum, it now gets the defaults. Mirror, 
proxy and authentication handling for it relies on the API resolving through 
`toResolvingRepositories`; not exercised.
   - The v4 model reader rejects `<reports>` (project and profile) and plugin 
`<goals>` in strict mode; the Maven 3 reader accepted them. `DefaultPomManager` 
and `DefaultOldArchetype` read non-strict, so any unknown element is now 
accepted too. `MavenJDOMWriter` cannot read those elements from the v4 model 
and leaves them untouched in the file (new test 
`testAddParentKeepsLegacyElements`).
   - `Model.Builder.parent(null)`/`modules(null)` on a builder made with 
`Model.newBuilder(model)` does not clear the value (null means inherit from 
base); `newBuilder(model, true)` is required. The first version of the port 
kept `<modules>` in the root archetype POM for this reason; the tests did not 
catch it, the fixture diff did.
   - `maven-parent` sets `<proc>none</proc>`, so 
`META-INF/maven/org.apache.maven.api.di.Inject` is maintained by hand (14 
classes).
   - `ApiRunner.createSession` has no transporter. The tests register `file` 
and Apache HTTP factories with `@Provides @Named` on a class passed to 
`injector.bindImplicit`; that pulls `maven-resolver-transport-file` and 
`-apache` 2.0.23 into test scope.
   
   **Consumers that break:** maven-archetype-plugin, in this repo (excluded 
from the reactor, not ported): `CreateProjectFromArchetypeMojo` 
(`setMavenSession`, `setRepositorySession`, `setRepositorySystem`, 
`setProjectBuildingRequest`, `setLocalRepository`, 
`setRemoteArtifactRepositories`), `IntegrationTestMojo` (`setMavenSession`, 
`Downloader.download`), `CreateArchetypeFromProjectMojo` 
(`setProject(MavenProject)`), `UpdateLocalCatalogMojo` and 
`DefaultArchetypeSelector` (`RepositorySystemSession`), 
`DefaultArchetypeGenerationConfigurator` (`VelocityComponent`, 
`RepositorySystemSession`). The plugin is a Maven 3 mojo and also relies on 
Sisu discovery. No other repository under the Apache Maven plugin repositories, 
shared, shared-4 or skins imports archetype-common.
   
   **Improvements:** drops `maven-core`, `maven-model`, `maven-artifact`, 
`maven-resolver-api`, `javax.inject`, `plexus-velocity`, and test-side 
`plexus-testing`, `maven-resolver-connector-basic`, 
`maven-resolver-transport-http`. `plexus-utils` and `plexus-xml` stay 
(generated archetype descriptor and catalog readers).
   
   **Recommendation:** the library ports without dropping behaviour except the 
remote-catalog and repository-policy gaps above. Do not release it before the 
plugin is ported to the Maven 4 mojo API and its 33 ITs run against it; keep 
the 3.x line for Maven 3 users.
   
   </details>
   
   <details><summary><b>maven-resolver-ant-tasks</b>: partial</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **partial**, 
3.0.0-SNAPSHOT, Java 17.
   
   Verified locally: `mvn verify -P run-its` with Maven 4.0.0-rc-7, JDK 21 → 59 
tests before, 60 after (new `AntModelResolverTest`), 0 failures; the 
POM-reading parity golden file and all 11 `ResolveTest` cases pass unchanged; 
spotless clean. Cost: `run-its` build 2:46 → 9:17, not profiled.
   
   Only the model and settings layer moves to the v4 API. Collection, 
resolution, install and deploy stay on the resolver's `RepositorySystem`.
   
   **Central finding: no public `Session` outside Maven.** Ant has no Maven 
runtime. The only route is `org.apache.maven.impl.standalone.ApiRunner` in 
`maven-impl`, which is internal. Its session has no transporter, cannot take 
the Ant project's `RepositorySystem` (local repository, mirrors, proxies, 
credentials), and a custom `ModelResolver` replaces the default only as a 
`@Named @Priority` class, not through `bindInstance`.
   
   **Public API changes** (internal packages, but the uber jar is what Ant 
users load)
   - `AntRepoSys.loadModel` and `Pom.getModel` return the immutable 
`org.apache.maven.api.model.Model`; `CreatePom` builds through new 
`addRepository`, `addDeveloper`, `setScm`.
   - `AntSecDispatcher`, `AntSettingsDecryptorFactory`, `SettingsUtils` 
removed: the v4 `SettingsBuilder` decrypts and converts profiles. A Maven 3 
`settings-security.xml` master password still decrypts.
   - The tasks need Java 17 (was 8).
   
   **Gaps**
   - Dependency POMs still go through the Maven 3 model builder via 
`maven-resolver-supplier-mvn4`; only the root POM uses the v4 `ModelBuilder`, 
so both builders are on the classpath.
   - A repository declared in a POM loses its policies: the v4 
`RemoteRepository` has only id, URL and protocol. Read from the API; no test 
covers it.
   - `BUILD_PROJECT` needs `.mvn` or `root="true"`, so the root POM is built 
with `BUILD_EFFECTIVE`/`CONSUMER_DEPENDENCY`; `setProcessPlugins(false)` has no 
equivalent.
   - The mvn4 supplier defaults to the transitive dependency manager; the 
classic one is now set explicitly. Other supplier defaults not diffed.
   - The shaded jar must merge `META-INF/maven/org.apache.maven.api.di.Inject` 
and leave `org.apache.maven.impl` and `api.spi` unrelocated; the uber jar grows 
4.95 MB → 8.22 MB.
   
   **Consumers that break:** none in the estate; user Ant builds need Java 17 
and see the v4 model from `Pom.getModel`.
   
   **Improvements:** drops `maven-settings-builder`, `plexus-cipher`, 
`plexus-sec-dispatcher`, `maven-resolver-supplier-mvn3`; fixes an NPE on an 
unreadable `settings.xml`.
   
   **Recommendation:** do not merge. The port rests on internal `ApiRunner`; 
ask apache/maven for a supported standalone `Session` factory that accepts a 
`RepositorySystem` and a `ModelResolver`. Keep 2.x on Maven 3 for Java 8 Ant 
users.
   
   </details>
   
   <details><summary><b>maven-indexer</b>: partial</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **partial**, 
8.0.0-SNAPSHOT, Java 17. `indexer-core` ported; `indexer-cli` and 
`search-backend-indexer` compile but fail at runtime (Sisu wiring), left 
unported.
   
   Verified locally: `mvn -B verify` with Maven 4.0.0-rc-7, JDK 21. 
`indexer-core`: 245 tests, 0 failures, 1 skipped, plus 5 ITs, before and after. 
`indexer-reader` 23 (1 skipped), `search-api` 4, `search-backend-smo` 15 (14 
skipped), `search-backend-remoterepository` 39: unchanged. `indexer-cli`: 7 
tests, 0 errors before, 5 errors after (its 6 ITs no longer reached). 
`search-backend-indexer`: 9 tests (7 skipped), 0 errors before, 2 errors after. 
The `examples` profile (`indexer-examples-*` tests, off by default) was not 
run. Spotless clean.
   
   **Public API changes**
   - `ArtifactContext.getPomModel()`: `org.apache.maven.model.Model` 
(maven-model) → `org.apache.maven.api.model.Model`. This is the only Maven type 
in the public API; `MinimalArtifactInfoIndexCreator` reads name, description 
and packaging from it.
   - POMs are read with `org.apache.maven.model.v4.MavenStaxReader` 
(`maven-support`), and `ArtifactLocator` no longer handles 
`XmlPullParserException`.
   - `@Named`/`@Singleton`/`@Inject` on all 19 components move from 
`javax.inject` to `org.apache.maven.api.di`. Sisu and Guice no longer discover 
them, so `WireModule`/`SpaceModule`, `InjectedTest` and Plexus lookups return 
nothing. Bare `@Named` is dropped because the v4 annotation requires a value.
   - Named creators (`min`, `jarContent`, `maven-plugin`, ...) and 
`List<IndexCreator>`/`Map<String, IndexCreator>` injection work in maven-di 
as-is.
   
   **Gaps**
   - `maven-compiler-plugin` has `<proc>none</proc>`, so 
`META-INF/maven/org.apache.maven.api.di.Inject` is maintained by hand (19 
classes); a new component missing from it fails with "No binding".
   - maven-di has no empty-collection injection: `DefaultIndexUpdater(…, 
List<IndexUpdateSideEffect>)` failed with a DI error because no side effect is 
bound. Fixed with `@Nullable` on the parameter (`maven-api-annotations`); the 
existing null check covers it. Behavioural difference: the list is `null`, not 
empty, when nothing is bound.
   - No API-level POM reader outside a container: `ModelXmlFactory` needs a 
Maven 4 injector, and `MavenStaxReader` sits in `maven-support`, which is not 
`maven-api-*`.
   - Tests: Sisu's `InjectedTest` replaced by a local `AbstractTestSupport` 
that builds `Injector.create().discover(...)`; no test removed.
   - Not ported: `archetype-catalog` (`ArchetypeDataSource`, optional, Maven 3 
artifact) and plexus-utils `StringUtils`/`FileUtils`/`Xpp3Dom`/DAG, which are 
not Maven APIs; `plexus-utils` is now declared explicitly because it used to 
arrive through `maven-model`.
   - Build: `javaVersion` 11 → 17 makes modernizer flag six `String.format` 
sites; modernizer pinned at 11 to keep them out of this change. 
`indexer-examples-spring` test-only `maven-model-builder` pinned to a new 
`maven3.version` (3.9.16) because it uses the v3 `ModelWriter`.
   
   **maven-api-core: not appropriate here.** Nothing in `indexer-core` uses 
`Session`, `Artifact`, `Project` or any service; the three files with Maven 3 
API use only the model. The port depends on `maven-api-model`, `maven-api-di`, 
`maven-api-annotations` and `maven-support` (which pulls `maven-xml`, 
`maven-api-settings`/`-toolchain`/`-metadata`/`-plugin`, all Java 17). For an 
artifact consumed by IDEs, repository managers and search tooling outside 
Maven, dropping the Maven dependency is the better port: only name, description 
and packaging are read, which a JDK StAX parse covers, and DI could be JSR 330 
only (`javax.inject`/`jakarta.inject`), which Sisu, Guice and Spring all 
honour. Forcing `org.apache.maven.api.di` on those consumers replaces a 
de-facto standard with a Maven-internal one. Not implemented; measured only the 
api.di port.
   
   **Consumers that break**
   - In this repo (compile, fail at runtime with Guice 
`NullInjectedIntoNonNullable` because Sisu finds no components): `indexer-cli` 
(`Components`, `NexusIndexerCli`, `NexusIndexerCliTest`), 
`search-backend-indexer` (`IndexerCoreSearchBackendPagingTest`, 
`IndexerCoreSearchBackendImplTest`); `indexer-examples-basic` 
(`BasicUsageExample`) and `indexer-examples-spring` use the same Guice/Sisu 
wiring, tests not run.
   - the Apache Maven repositories plugins, shared, shared-4 and misc: no Java 
import of `org.apache.maven.index` and no `org.apache.maven.indexer` dependency 
outside the repo itself. External consumers (IDE, repository manager, search 
tooling) cannot be checked from here; anyone calling 
`ArtifactContext.getPomModel()` or wiring through Sisu breaks.
   
   **Improvements:** drops `javax.inject`, `org.eclipse.sisu.inject` and 
`guice` (provided) from `indexer-core`, and `maven-model`.
   
   **Recommendation:** do not merge as is. Keep `indexer-core` 7.x on JSR 330 
for the non-Maven consumers; if a Maven 4 line is wanted, prefer replacing 
`MavenXpp3Reader` with a small StAX read and keeping `javax.inject`, rather 
than `org.apache.maven.api.di`.
   
   </details>
   
   


-- 
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