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]