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

   ### Wave 4 findings, part 4 of 4: maven-remote-resources-plugin to 
maven-toolchains-plugin
   
   Each plugin is a local branch `agent/mvn4-api` with a "Build with Maven 4 
only" commit and a "Port to the Maven 4 API" commit; the PRs are not opened yet.
   
   <details><summary><b>maven-remote-resources-plugin</b>: ported</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **ported** (reduced 
supplemental-model merging, see Gaps), 4.0.0-beta-1-SNAPSHOT, Java 17.
   
   Verified locally: `mvn verify -Prun-its` with Maven 4.0.0-rc-7, JDK 21 → 11 
unit tests, 9 failsafe ITs and 7 invoker ITs before (8:39 min), 11, 9 and 7 
after (4:10 min), 0 failures; spotless clean. The unit test class is rewritten 
(see Gaps), the ITs are untouched.
   Snapshots consumed from the local repository (not rebuilt here): 
`maven-filtering` 4.0.0-beta-2-SNAPSHOT, `maven-archiver` 4.0.0-beta-6-SNAPSHOT 
(`org.apache.maven.shared`), `maven-common-artifact-filters` 4.0.0-SNAPSHOT 
(the agent/mvn4-api port).
   
   **v4 equivalents**
   | Was | Is |
   |---|---|
   | `ProjectBuilder.build(Artifact, request)` → `MavenProject` | 
`Session.resolveArtifact` of the `pom` artifact, then 
`ModelBuilder.newSession().build(ModelBuilderRequest…requestType(CONSUMER_DEPENDENCY).source(Sources.resolvedSource(pom,
 key)))` → `getEffectiveModel()`. `api.ProjectBuilder` is unusable here: 
`ProjectBuilderResult.getProject()` is empty for a repository POM because 
`DefaultSession.getProject` returns null when the project has no base 
directory. `BUILD_EFFECTIVE` fails on invalid dependency POMs 
(`'distributionManagement.status' must not be specified` for 
`maven-plugin-api:2.0`); `CONSUMER_DEPENDENCY` tolerates them like 
`VALIDATION_LEVEL_MINIMAL` did (MRRESOURCES-121 IT). |
   | `MavenProject.getArtifacts()` / `getDependencyArtifacts()` | 
`Session.collectDependencies(project, TEST_RUNTIME)` flattened / 
`root.getChildren()`, as `Dependency` sets fed to the v4 
common-artifact-filters |
   | `RepositorySystem.resolveArtifact` + `ArtifactHandlerManager` | 
`Session.requireType(type)` (extension, classifier) + 
`Session.resolveArtifact(artifact, 
ProjectManager.getRemoteProjectRepositories(project))` |
   | `MavenSession.getProjects()` output dirs | 
`Project.getOutputDirectory(ProjectScope.MAIN / TEST)` |
   | `project.getResources().add(Resource)` | 
`ProjectManager.addSourceRoot(project, scope, Language.RESOURCES, path)` |
   | `project.getResources()` iteration | 
`ProjectManager.getEnabledSourceRoots(project, MAIN, Language.RESOURCES)`, 
`SourceRoot.stringFiltering()` |
   | `MavenXpp3Reader` for supplements | 
`ModelXmlFactory.read(XmlReaderRequest)` |
   | plexus `ResourceManager` injection | `new DefaultResourceManager(Map<id, 
loader>)` built by hand; still exposed as `$locator` |
   
   **Velocity context objects**
   - `project` and each element of `projects`: `MavenProject` → 
`RemoteResourcesProject` (new, public), a wrapper over the immutable 
`org.apache.maven.api.model.Model` with the descriptive getters (`groupId`, 
`artifactId`, `version`, `packaging`, `name`, `description`, `url`, 
`inceptionYear`, `organization`, `licenses`, `developers`, `contributors`, 
`mailingLists`, `scm`, `issueManagement`, `ciManagement`, 
`distributionManagement`, `build`, `dependencies`, `properties`, `id`, 
`basedir`, `model`). Returned values are v4 model classes (same getter names); 
`properties` is a `Map<String,String>`.
   - `$project.artifact` keeps the textual form 
`groupId:artifactId:type:version` (type = the model packaging), so the bundled 
`DEPENDENCIES` template output is unchanged (MRRESOURCES-121 asserts 
`…maven-plugin-api:jar:2.0`). The object is no longer an `Artifact` (no 
`getFile()`).
   - `projectsSortedByOrganization` keys are 
`org.apache.maven.api.model.Organization`; `projects` sort by groupId, 
artifactId, version.
   - Unchanged: `presentYear`, `projectTimespan`, `locator`, user `properties`.
   - Gone: every `MavenProject`-only method (`getFile`, `getParent`, 
`getArtifacts`, `getBuild().getResources()` as mutable, …); templates using 
them need `$project.model`.
   
   **Public API changes**
   - Mojos implement `org.apache.maven.api.plugin.Mojo`; `@Inject` fields 
(`Session`, `Project`, `Log`, `MavenFileFilter`); constructors are no-arg (a 
constructor with parameters fails at lookup: the generated `…MojoFactory` calls 
`<init>()`). Protected `mavenSession` → `session` (`api.Session`), `project` is 
`api.Project`; abstract `getAllDependencies()` / `getDirectDependencies()` 
return `Set<org.apache.maven.api.Dependency>`; `getProjects()` returns 
`List<RemoteResourcesProject>`; `getSupplement`, `mergeModels` use 
`api.model.Model`.
   - `ModelInheritanceAssembler.assembleModelInheritance` returns the merged 
`Model` instead of mutating; `ModelUtils` is removed.
   - Defaults `${basedir}/src/main/resources` and 
`${basedir}/src/main/appended-resources` became `${project.basedir}/…`: Maven 4 
does not evaluate `${basedir}` in `@Parameter` defaults (the `bundle` goal 
silently skipped with "skip non existing resourceDirectory 
${basedir}/src/main/resources").
   
   **Gaps**
   - `SourceRoot` is immutable, so a project resource that overrides a bundle 
resource is no longer excluded from the project's resources 
(`resource.addExclude`); both copies reach the resources plugin. 
ITFilterLocalOverride and ITGenerateFromOverride pass.
   - Supplemental-model assembly is reduced: descriptive metadata, properties, 
dependencies, dependencyManagement, repositories and the build 
directories/filters/resources are merged; plugins, pluginManagement, extensions 
and reporting are not (no v4 API to merge models, `maven-impl`'s assembler is 
internal). They only matter if a template reads them. ITSupplementalArtifact 
passes.
   - `requiresDependencyResolution = TEST` has no attribute in use; 
dependencies are collected on demand. `resolveScopes` was already unused.
   - The filtering component needs a `BuildContext`: `Providers` (`@Named`, 
`@Provides ThreadBuildContext`) plus `plexus-build-api` and 
`org.eclipse.sisu.plexus` at runtime (for `AbstractLogEnabled`), as in 
maven-resources-plugin.
   - Tests: `RemoteResourcesMojoTest` no longer uses `AbstractMojoTestCase` and 
is rebuilt on Mockito mocks of `Session`/`Project`/`ProjectManager` (same 11 
scenarios, renamed to camelCase). Removed, with reason: `stub/ArtifactStub`, 
`MavenProjectBasicStub`, `MavenProjectBuildStub`, `MavenProjectResourcesStub`, 
`ModelStub` (v3 `MavenProject` stubs with no v4 counterpart), 
`src/test/resources/unit/rrmojotest/*.xml` (mojo configs for the old lookup 
harness). The unit tests therefore do not exercise real dependency resolution; 
the ITs do.
   
   **User-visible changes:** requires Maven 4; Velocity templates that call 
`MavenProject` methods beyond the list above break; the `${basedir}` defaults 
are now `${project.basedir}`; local resources overriding a bundle are copied 
twice (same content). ASF parent POMs bind this plugin, so they need the 4.x 
plugin on Maven 4 only. No Java code under the Apache Maven repositories 
imports `org.apache.maven.plugin.resources.remote`.
   
   **Improvements:** drops `maven-core`, `maven-model`, `maven-model-builder`, 
`maven-plugin-api`, `maven-artifact`, `maven-resolver-api/provider/util`, 
`maven-plugin-annotations`, `javax.inject`, and from tests junit4, the vintage 
engine, `maven-plugin-testing-harness` and `maven-resolver-impl`; adds 
`maven-api-core/annotations/model/di` (provided), `plexus-build-api`, 
`mockito-core` 5.24.0 (tests, replaces the harness stubs).
   
   **Recommendation:** port for Maven 4; keep the 3.x line for Maven 3. Ask 
core for a `ProjectBuilder` result that works for repository POMs (or document 
`ModelBuilder` + `CONSUMER_DEPENDENCY`), and for a documented `${basedir}` 
alias in parameter defaults.
   
   </details>
   
   <details><summary><b>maven-scm-publish-plugin</b>: ported</summary>
   
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **ported**, 
4.0.0-beta-1-SNAPSHOT, Java 17.
   
   Verified locally: `mvn verify` with Maven 4.0.0-rc-7, JDK 21 → no unit tests 
exist, before or after; `mvn verify -Prun-its` → 5 passed, 0 failed before 
(5m09s) and after (4m57s); spotless clean. Also run by hand with the installed 
plugin: credentials from a settings `<server>` (see Gaps) and a no-project 
publish to a local bare git repo (BUILD SUCCESS, commit and `index.html` 
present, seed file deleted as expected). Shared snapshots consumed: none 
(maven-scm 2.2.1 release; the maven-scm library modules use no Maven API and 
are used unchanged; maven-release-manager is dropped, not ported).
   
   **Public API changes** (Mojo base classes, for subclasses only)
   - `AbstractScmPublishMojo` implements `org.apache.maven.api.plugin.Mojo`; 
constructor `(ScmManager, ScmRepositoryConfigurator)` is gone; `@Inject` fields 
`Log`, `Session`, `Prompter`; `ScmPublishPublishScmMojo.project` is now 
`org.apache.maven.api.Project`; the `settings` field is gone; 
`execute()`/`scmPublishExecute()` throw the unchecked `MojoException`.
   - `@Mojo(projectRequired = false, aggregator = true)` replaces 
`requiresProject = false`.
   - New package-private `ScmManagerFactory` (builds the `ScmManager`).
   
   **Gaps**
   - `ScmManager` and `ScmRepositoryConfigurator` cannot be injected. Both are 
Sisu JSR 330 components (`META-INF/sisu/javax.inject.Named`), which the v4 
plugin container does not read, and 
`ScmRepositoryConfigurator.getConfiguredRepository(ReleaseDescriptor, 
org.apache.maven.settings.Settings)` takes the v3 `Settings` type, which 
`Session.getSettings()` (`org.apache.maven.api.settings.Settings`) does not 
provide. I did not try to keep `maven-release-manager`. Replacement: 
`ScmManagerFactory` reads the Sisu index from the plugin class loader, 
instantiates each `@Named` `ScmProvider` (first hint wins, as in 
`DefaultScmManager`) into a `BasicScmManager`; debug log shows `git`, `jgit`, 
`hg`, `svn` registered. A provider needs a no-arg constructor or the Plexus 
`Prompter` constructor (jgit, served by an adapter over the v4 
`org.apache.maven.api.services.Prompter`); any other is skipped with a warning. 
This is the piece maven-scm would have to fix properly (a non-Sisu way to 
obtain a `Scm
 Manager`, such as a `ServiceLoader` registry).
   - Settings/servers: `Session.getSettings().getServers()` is a plain list, so 
the `getServer(id)` lookup and the host fallback (`host[:port]`) are 
reimplemented in the mojo, along with the 
username/password/privateKey/passphrase precedence of 
`DefaultScmRepositoryConfigurator`. The v4 API has no decrypt service; Maven 
4's `DefaultSettingsBuilder` decrypts settings itself (read in the maven-4.0.x 
checkout at e8fd05aeee), so the mojo uses the values as given. Not run against 
an encrypted password. Observed: `svn --username alice --password ... ` taken 
from `<server id="myserver">` via 
`${project.model.distributionManagement.site.id}`.
   - Plugin expressions: `${project.distributionManagement.site.url}` and 
`${project.name}` do not evaluate in v4 (the evaluator reflects on 
`api.Project`, which has no such getters). The first ITs failed with "The scm 
url cannot be null". Defaults are now 
`${project.model.distributionManagement.site.url|id}` and 
`${project.model.name}`; `${project.reporting.outputEncoding}` still resolves 
as a property.
   - `${settings}` and `${project}` parameters have no v4 form; replaced by 
`Session.getSettings()` and an injected `Project`. With `projectRequired = 
false` and no pom, the injected `Project` is null and the mojo handles it 
(publish without a project verified).
   - Left as is, warnings only: `maven-shared-utils` `MessageUtils` 
(deprecated; the v4 `MessageBuilderFactory` exists), `Model.getModules()` and 
`ScmProviderRepository.setPersistCheckout` (deprecated).
   
   **User-visible changes**
   - Maven 4 only; Java 17 to run.
   - Parameters `settings` and `project` removed; all other parameter names, 
properties and the `maven.site.deploy.skip` alias are unchanged (alias present 
in the generated `plugin.xml`).
   - Default expressions changed as above; users overriding `pubScmUrl`, 
`serverId` or `checkinComment` are unaffected. Without a project the default 
checkin comment still contains the literal `${project.model.name}` (Maven 3 
behaviour not compared).
   - Third-party SCM providers added as plugin dependencies are found only if 
they publish the Sisu index and have a supported constructor.
   
   **Improvements:** drops `maven-release-api`, `maven-release-manager`, 
`maven-core`, `maven-model`, `maven-settings`, `maven-plugin-api`, 
`maven-plugin-annotations`; adds the `maven-api-*` jars (provided). 
`javax.inject` moves from provided to runtime (needed to read `@Named` hints; 
providers already depend on it) and `plexus-interactivity-api` 1.4 becomes 
explicit (already transitive via the jgit provider; the adapter implements its 
interface).
   
   **Recommendation:** port for the Maven 4 line, keep 3.x for Maven 3. The 
port works, but the in-plugin provider bootstrap is a workaround; ask maven-scm 
for a non-Sisu `ScmManager` factory before releasing.
   
   </details>
   
   <details><summary><b>maven-scripting-plugin</b>: ported</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **ported**, 
4.0.0-beta-1-SNAPSHOT, Java 17.
   
   Verified locally: `mvn verify` with Maven 4.0.0-rc-7, JDK 21 → 1 test before 
and after, 0 failures; `-Prun-its` 5/5 ITs pass before and after (whole suite, 
no time-box hit); spotless clean. Not measured: running the ported plugin under 
Maven 3.
   
   Uses `maven-api-core`/`maven-api-di`/`maven-api-annotations` 4.0.0-rc-7 
(provided) and plugin-tools 4.0.0-beta-1. No shared component needed.
   
   **User-visible changes**
   - Goal `scripting:eval` and its parameters (`engineName`, `script`, 
`scriptFile`, `scriptResource`) are unchanged.
   - The plugin no longer runs on Maven 3 (v4 `Mojo`, `@Inject`).
   - Script-visible bindings (the `GLOBAL_SCOPE` `Bindings` passed to every 
engine): the names stay `project` and `log`, the types change.
     - `project`: `org.apache.maven.project.MavenProject` → 
`org.apache.maven.api.Project`. Still there: `groupId`, `artifactId`, 
`version`, `basedir` (now `java.nio.file.Path`, was `File`), `model`, `build` 
(now `org.apache.maven.api.model.Build`), `parent` (now `Optional<Project>`), 
`artifacts` (now `List<ProducedArtifact>`). Gone: `getFile()` (use `pomPath`), 
`getProperties()` (use `model.properties`), `getName()`/`getDescription()` (use 
`model.name`/`model.description`), `getCollectedProjects()`, `getArtifact()`, 
`getRemote*Repositories()`, `getPluginArtifacts()`, `getCompileSourceRoots()`.
     - `log`: `org.apache.maven.plugin.logging.Log` → 
`org.apache.maven.api.plugin.Log`. `debug/info/warn/error` with `CharSequence` 
and/or `Throwable`, and `isXxxEnabled()`, are present; the `(CharSequence, 
Throwable)` overloads exist too.
     - No `session` binding before or after; not added.
   - Java engine (`Maven-Scripting-Java-Engine`): the generated class now 
imports `org.apache.maven.api.Project` and `org.apache.maven.api.plugin.Log`, 
so `$project` and `$log` change type the same way. The engine's compile 
classpath is `${maven.home}/lib/maven-*` plus the test/plugin classpath; on 
Maven 4 that includes `maven-api-core`, so it compiles.
   - Groovy scripts using `project.artifactId` (the 4 Groovy ITs) work 
unchanged; Groovy property access maps onto the `Project` getters.
   - Error reporting: `MojoExecutionException` (script error) and 
`MojoFailureException` (no engine for name/extension) both become 
`MojoException`, so the "BUILD FAILURE" vs "error" distinction is gone.
   - `ContextAwareEngine.setLog(Log)` is public API for custom engines: 
parameter type is now the v4 `Log`.
   
   **Gaps:** none. Everything used has a v4 equivalent.
   
   **Improvements:** drops `maven-plugin-api`, `maven-core`, 
`maven-plugin-annotations`. `<prerequisites><maven>` follows `${mavenVersion}`.
   
   **Recommendation:** port; publish as a 4.x line and keep 3.x for Maven 3 
users. Release notes must list the binding type change, since user scripts are 
the only "consumers" and they are not visible to us.
   
   </details>
   
   <details><summary><b>maven-shade-plugin</b>: partial</summary>
   
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **partial**, 
4.0.0-beta-1-SNAPSHOT, Java 17.
   
   Verified locally: `mvn -B -ntp verify` with Maven 4.0.0-rc-7, JDK 21 → 72 
unit tests before and after, 0 failures, 0 skipped; `mvn verify -Prun-its` → 
Passed 85, Failed 0, Skipped 1 before (19m39s, contended by other builds) and 
after (13m59s); the skipped IT is `MSHADE-185` ("SKIPPED due to JRE version") 
both times, so the system-scoped-dependency path of the reduced POM is 
unexercised. `spotless:check` clean. Shared snapshots consumed: none. Not 
measured: parallel (`-T`) builds beyond the existing `MSHADE-413-parallel` IT, 
JDK 17.
   
   **Public API changes**
   - `Shader.shade` throws the unchecked 
`org.apache.maven.api.plugin.MojoException` instead of checked 
`MojoExecutionException`. Third-party `Shader` implementations break at compile 
time and need `@Named("<hint>")` from `org.apache.maven.api.di` plus an entry 
in `META-INF/maven/org.apache.maven.api.di.Inject` (`<proc>none</proc>` in the 
parent, so nothing generates it for test classes). `DefaultShader` is 
`@Named("default")` with `@Inject` on the no-arg constructor.
   - `MinijarFilter` public constructors: `(MavenProject, Log, ...)` becomes 
`(String projectId, Path projectArtifact, Path outputDirectory, 
Map<String,Path> dependencies, Log, ...)`; `Log` is 
`org.apache.maven.api.plugin.Log`.
   - `UseDependencyReducedPom.createPomReplaceTransformers(MavenProject, File)` 
takes `org.apache.maven.api.Project`; 
`ShadeMojo.updateExcludesInDeps(MavenProject, List, List)` becomes `(List, 
List)` over `org.apache.maven.api.model.Dependency`.
   - Removed `org.apache.maven.plugins.shade.pom.PomWriter`, `MavenJDOMWriter` 
(1941 lines) and `Counter`; the reduced POM is written with `ModelXmlFactory`.
   - Unchanged: `ResourceTransformer`, `ReproducibleResourceTransformer`, 
`Relocator`, `Filter` and every built-in transformer. None references a Maven 
type, so third-party transformers recompile as they are 
(`MSHADE-363_old-Transformer` passes with a Spring Boot transformer on the 
plugin classpath). `jdom2` and `plexus-utils` stay because built-in 
transformers use them.
   - `ShadeMojo` implements `org.apache.maven.api.plugin.Mojo` with `@Inject` 
`Log`/`Session`/`Project`/`Map<String,Shader>`; new package-private 
`ResolvedArtifact` replaces `org.apache.maven.artifact.Artifact` inside the 
mojo.
   
   **Gaps**
   - The project's POM file cannot be replaced. v3 called 
`MavenProject.setFile(dependencyReducedPom)`; `Project` has no setter, and 
`ArtifactManager.setPath(project.getPomArtifact(), drp)` has no effect on 
install (tried: installed `-build.pom` still lists the shaded dependency). The 
call is dropped. Measured on Maven 4 with the 3.6.3 plugin: `setFile` only 
changed the installed `*-build.pom`; the consumer POM (`*.pom`) is generated 
from the model and still lists the shaded dependency. So Maven 4 core, not the 
plugin API, decides what consumers see; a model-level hook would be needed.
   - Main artifact replacement needs no v4 call: the mojo renames the shaded 
file over the path from `ArtifactManager.getPath(project.getMainArtifact())`. 
Attached artifacts use `ProjectManager.attachArtifact(project, 
session.createProducedArtifact(g, a, v, classifier, ext, null), path)`; 
classified sources/tests resolve through `session.resolveArtifact(coordinates, 
projectManager.getRemoteProjectRepositories(project))`. `getMainArtifact()` is 
empty for `pom` packaging.
   - `ProjectBuilder` cannot re-read the reduced POM: 
`DefaultProjectBuilder.doBuild` builds a bare `ProjectBuildingRequest` (no root 
directory, properties or profiles), so a parent reachable only through 
`relativePath` fails with "Non-resolvable parent POM" 
(`dep-reduced-pom-with-local-parent`). The port collects the dependencies it 
just wrote (`DependencyResolverRequest` with `rootArtifact`, `dependencies`, 
`managedDependencies`, `verbose(true)`, `TEST_RUNTIME`) instead. Consequences: 
the written POM is no longer parsed back, so a malformed reduced POM is no 
longer caught in the plugin, and the MSHADE-467 lock around the build is gone.
   - `DependencyCoordinatesFactory.create(Session, 
org.apache.maven.api.model.Dependency)` drops scope, optional and exclusions 
(it passes only g:a:v:classifier:type). With it the graph lost `provided` and 
the exclusions and `dep-reduced-pom-artifactset-provided-excludes` (MSHADE-311) 
failed. The mojo fills `DependencyCoordinatesFactoryRequest` itself and 
implements `api.Exclusion`.
   - No `threadSafe` and no `requiresDependencyResolution` on `@Mojo`: 
dependencies are resolved in `execute()` with 
`DependencyResolver.resolve(session, project, PathScope.MAIN_RUNTIME)`; 
`getDependencies()` is a `LinkedHashMap`, so jar order (first wins on duplicate 
resources) is kept. No IT isolates the ordering.
   - `MavenProject.getOriginalModel()` has no equivalent; the raw model is read 
from `project.getPomPath()` with `ModelXmlFactory` (`strict(false)`).
   - DI: injecting `Shader` picks an arbitrary implementation once a build adds 
another (`shading-with-java-8-sources` has the test jar with `MockShader` on 
the plugin classpath and sets no `shaderHint`, and it ran `MockShader`); the 
mojo injects `Map<String,Shader>` and looks up `shaderHint` or `default`. A 
class with two constructors needs `@Inject` on one.
   - Parameter default `${basedir}/dependency-reduced-pom.xml` does not 
evaluate in v4 (created a literal `${basedir}` path); now 
`${project.basedir}/...`, same value.
   - Reduced-POM `parent.relativePath` (apache/maven-shade-plugin#813, #843, 
both open): master does not fix it. On rc-7 a project with `<relativePath/>` in 
its parent fails at `shade` with `'parent.relativePath' ... points at 'pom.xml' 
which resolves to org.example:app-emptyrel instead of the declared parent`; the 
`..` layout from #813 did not fail on rc-7 with master's code in my repro. Root 
cause: the 3.x code resolves an empty relativePath against the basedir and 
writes `pom.xml`. The port keeps an empty path empty, and leaves an unset path 
unset: the v4 model writer writes every non-null field, so writing the computed 
`../pom.xml` made Maven 4 reject the reduced POM (verified with `mvn -f 
dependency-reduced-pom.xml validate`). Not the approach of #843 (empty path 
when `..` is not the real parent); that PR's case and mine are different inputs.
   - Unverified: parallel builds, `generateUniqueDependencyReducedPom` under 
load, `MSHADE-185` system scope (IT skipped), mojo configuration of third-party 
transformers that need injection.
   
   **User-visible changes**
   - Runs on Maven 4 only and needs Java 17; a 3.x line must stay for Maven 3 
users. Goal, parameter names and `-D` properties are unchanged; `threadSafe` is 
not declared.
   - Reduced POM is written by the v4 model writer: canonical element order, 
`https://maven.apache.org/xsd/maven-4.0.0.xsd` in `schemaLocation`, default 
values (`<relativePath>../pom.xml`) omitted; all reduced-POM ITs pass.
   - Install/deploy publish the original `*-build.pom` (on Maven 4 the 3.6.3 
plugin published the reduced one there); the consumer POM is unchanged by 
either.
   - `<relativePath/>` in the shaded project's parent now works on Maven 4 
(fails on master).
   - Consumers in the Apache Maven repositories that use the plugin 
(indexer-cli, resolver-ant-tasks, surefire-shared-utils, surefire-shadefire, 
doxia converter, modello-core) reference only built-in transformers by class 
name; no source change, but each needs the new plugin version under Maven 4. 
Maven 4's `mvnup` (`PluginUpgradeStrategy`) upgrades shade to at least 3.5.0 
and skips projects with custom transformers; it knows nothing of 4.x.
   
   **Improvements:** drops `maven-plugin-api`, `maven-core`, `maven-model`, 
`maven-artifact`, `maven-resolver-provider`, `maven-plugin-annotations`, 
`javax.inject`, `sisu-maven-plugin`, and about 2000 lines of generated JDOM 
writer; adds `maven-api-core`, `maven-api-di`, `maven-api-model`, 
`maven-api-annotations` (provided). Test scope: `junit-vintage-engine`, `junit` 
(explicit) and `maven-plugin-testing-harness` go; `guice` is added for 
`TransformerTesterRule` (sisu.plexus needed it and `maven-core` no longer 
supplies it); `junit`/`hamcrest-core` stay in `dependencyManagement` because 
`xmlunit-legacy` pulls junit 4 in and surefire then starts the vintage engine.
   
   **Tests rewritten, none removed:** `ShadeMojoTest` (5 tests) from JUnit 3 
`AbstractMojoTestCase` to JUnit 5 with Mockito and `new DefaultShader()`; 
`MinijarFilterTest` (2 tests) from a `MavenProject` mock to the new 
constructor. 72 tests before and after. New 
`src/test/resources/META-INF/maven/org.apache.maven.api.di.Inject` lists 
`MockShader`.
   
   **Recommendation:** port for the Maven 4 line, keep 3.x for Maven 3. Two 
things block a full-parity claim: the reduced POM cannot become the published 
POM through any v4 API (a core/consumer-POM question to raise on apache/maven), 
and the `ProjectBuilder` request cannot carry session context. Worth issues: 
`DependencyCoordinatesFactory.create(Session, model.Dependency)` dropping 
scope/exclusions, and `ProjectBuilderRequest` lacking root 
directory/properties. Consider folding the `<relativePath/>` fix into a 3.x PR 
against #813/#843 first, since master is broken for that input today.
   
   </details>
   
   <details><summary><b>maven-toolchains-plugin</b>: ported</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **ported**, 
4.0.0-beta-1-SNAPSHOT, Java 17. All four goals on `org.apache.maven.api`; no 
test or IT removed.
   
   Verified locally: Maven 4.0.0-rc-7, JDK 21. `mvn -B -ntp verify`: 1 test 
(`ToolchainDiscovererTest`), 0 failures, before and after. `-Prun-its`: 8 of 8 
ITs before (old plugin on Maven 4), 8 of 8 after. 
`display-discovered-jdk-toolchains` and `generate-jdk-toolchains-xml` have no 
IT; both were run by hand against the built plugin and print/write the 5 local 
JDKs. Spotless clean.
   
   **Do the goals still have a job under Maven 4? Yes, both `toolchain` and 
`select-jdk-toolchain`.** rc-7 `DefaultToolchainManager` only stores and reads 
the build context (`toolchain-<type>`); nothing in core selects and stores a 
toolchain. Core points at this plugin: `checkJdkSourceLevelCompatibility` logs 
"run 'mvnup' to add the maven-toolchains-plugin" and mvnup 
`ToolchainPluginStrategy` adds `select-jdk-toolchain`.
   
   **Public API changes**
   - Mojos implement `org.apache.maven.api.plugin.Mojo` with `@Inject 
Log`/`Session` (`org.apache.maven.api.di`); `requiresProject = false` becomes 
`projectRequired = false`; `defaultPhase` is a string. Goal names and parameter 
names/properties unchanged.
   - `ToolchainManagerPrivate` becomes 
`session.getService(ToolchainManager.class)` (`getToolchains`, 
`storeToolchainToBuildContext`); `ToolchainPrivate` becomes 
`org.apache.maven.api.Toolchain`; toolchains XML goes through 
`ToolchainsXmlFactory`; models are the immutable 
`org.apache.maven.api.toolchain` types with `XmlNode` configuration.
   - `ToolchainsRequirement` (public) keeps its getters; its package-private 
field is replaced by `fromXmlNode(XmlNode)`. `ToolchainConverter` and 
`ToolchainsComponentConfigurator` (Plexus converter plus custom configurator 
`toolchains-requirement-configurator`) are deleted: the `toolchains` parameter 
is now an `XmlNode`, which rc-7's enhanced configurator populates directly 
(confirmed by the `toolchain` ITs).
   - `ToolchainDiscoverer` is an api.di `@Named @Singleton` with a constructor 
taking `ToolchainsXmlFactory` (was no-arg); it is public, so callers 
constructing it break.
   - Discovery no longer aborts on one unreadable JDK: a JDK whose `java 
-XshowSettings` fails is skipped (before, the NPE was caught and discovery 
returned an empty result).
   - The cache and generated toolchains XML now use the 1.2.0 toolchains 
namespace (writer of rc-7).
   
   **Gaps**
   - No API turns a `ToolchainModel` into a `Toolchain` for an arbitrary model: 
the `jdk` `ToolchainFactory` is not bound in a plugin's injector (`No binding 
... @Named("jdk") ToolchainFactory`). `select-jdk-toolchain` therefore wraps 
discovered and current JDK models in a private `JdkToolchain` (type, model, 
`findTool`); `storeToolchainToBuildContext` only uses type and model, and core 
re-creates the real toolchain from the stored model.
   - `RequirementMatcherFactory` is compat-only. Matching is done locally on 
`model.getProvides()`: `version` through 
`session.parseVersionConstraint(..).contains(session.parseVersion(..))`, `env` 
by the existing regex, everything else case-insensitive equals. The jdk 
factory's own matcher also does not know `env`, so 
`toolchain.matchesRequirements` could not have been reused.
   - `Xpp3Dom` replaced by `XmlNode` (`child("jdkHome").value()`); the plugin 
no longer needs `plexus-xml`.
   - No generated-by-processor surprises: `<proc>` is on; the 
`META-INF/maven/org.apache.maven.api.di.Inject` index lists the four Mojo 
factories and `ToolchainDiscoverer`.
   - Custom toolchain types: a v4 `services.ToolchainFactory` contributed by an 
extension is found by the core manager only when it is registered through the 
Sisu index (`javax.inject.@Named("custom")` plus 
`sisu-maven-plugin:main-index`), not through 
`META-INF/maven/org.apache.maven.api.di.Inject` alone (`Missing toolchain 
factory for type: custom` with the api.di index). The IT fixture 
`setup-custom-toolchain` is ported that way.
   
   **User-visible changes**
   - Requires Maven 4 (`<prerequisites>` follows `mavenVersion` 4.0.0-rc-7).
   - Failure messages carry `MojoException` instead of `MojoFailureException` 
(IT `missing-toolchain` assertion updated).
   - The `toolchains` parameter is logged at debug level as XML, not 
`ToolchainsRequirement{...}` (IT `select-jdk-toolchain-range` now asserts the 
`Required toolchain:` info line instead).
   - Custom toolchain factories written against the compat `ToolchainFactory` 
still work through core's bridge; ones written for the v4 API need the Sisu 
index, see Gaps.
   
   **Improvements:** drops `maven-core`, `maven-plugin-api`, 
`maven-plugin-annotations`, `javax.inject`, `org.eclipse.sisu.plexus`, 
`plexus-xml`, `slf4j-api` 1.7 (now provided 2.0.x) and `sisu-maven-plugin`.
   
   **Recommendation:** merge-worthy as the 4.x line, with the jdk-factory and 
`env` matcher gaps filed against apache/maven: a way to create a `Toolchain` 
from a `ToolchainModel` would remove the private `JdkToolchain` wrapper.
   
   </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