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

   ### Wave 4 findings, part 2 of 4: maven-doap-plugin to maven-jarsigner-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-doap-plugin</b>: ported</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **ported**, 
4.0.0-beta-1-SNAPSHOT, Java 17. Five approximations, all under Gaps; the 
release listing and the `artifact` parameter differ from Maven 3 behaviour in 
ways the unit tests cannot show.
   
   Verified locally: `mvn verify` with Maven 4.0.0-rc-7, JDK 21 → 15 tests 
before and after, 0 failures, 0 skipped; `mvn verify -Prun-its` → 4 of 4 ITs 
pass before and after; `spotless:check` clean. Smoke runs on rc-7 against Maven 
Central (scratch projects, not committed): a project whose releases exist on 
Central (release list, `file-release` URLs and `created` date came out right) 
and `<artifact>` set to `org.apache.maven:maven-artifact:3.9.9` (parent 
inherited, URL and SCM effective). The pre-port plugin could not be compared on 
the same projects: under rc-7 it fails with `NoClassDefFoundError: 
org/codehaus/plexus/util/xml/XmlStreamReader` as soon as a repository returns 
metadata, which none of the ITs do.
   
   **Public API changes**
   - `DoapMojo` implements `org.apache.maven.api.plugin.Mojo`, `@Mojo(name = 
"generate")` from `org.apache.maven.api.plugin.annotations`; `execute()` throws 
`MojoException`. `project` is the injected `org.apache.maven.api.Project`, 
dates and model getters read from `project.getModel()`.
   - Removed fields and read-only parameters: `localRepository`, 
`projectBuildingRepositories`, `remoteRepositories`, `repositorySystemSession`, 
`settings`, `project` (as a parameter).
   - `DoapUtil.interpolate(String, Project, Settings)` takes the v4 `Project` 
and `org.apache.maven.api.settings.Settings`. 
`DoapUtil.getContributorsWith*Role(List<Contributor>)` lose the `I18N` argument 
and use `org.apache.maven.api.model.Contributor`. 
`ASFExtOptionsUtil.isASFProject(Project)` and `findChair`/`findPMCMembers` take 
`org.apache.maven.api.model.Developer`.
   - Modello classes (`DoapOptions`, `ASFExtOptions`, `ExtOptions`, 
`DoapArtifact`) are unchanged.
   
   **Gaps** (rc-7 `maven-api-core`, `maven-api-model`, `maven-api-settings`)
   - Building a `Project` from coordinates: the v4 `ProjectBuilder` takes a 
path or a `Source`, not an artifact. `<artifact>` now resolves the POM with 
`Session.resolveArtifact` and builds from its path. A build from a `Source` 
(`Sources.resolvedSource`) returns an empty `Optional<Project>` with no 
problems listed, because `DefaultSession.getProject` drops a project without 
base directory; the plugin used it first and silently fell back to the current 
project. The request builder has no validation level, so Maven 3's 
`VALIDATION_LEVEL_MINIMAL` is gone.
   - `RemoteRepository` has no release or snapshot policy (`getId`, `getType`, 
`getUrl`, `getProtocol` only). The plugin picks the first repository that 
serves releases but not snapshots; it now reads the policies from the 
repository of the same id in `project.getModel().getRepositories()`. A 
repository that is not declared there, such as a mirror or one from 
`settings.xml`, is taken as releases only, which can change which repository is 
chosen.
   - No repository metadata service. `Transport` (from `TransportProvider`) 
fetches `g/a/maven-metadata.xml` by relative URI, and the XML is parsed with 
`MetadataStaxReader`, which ships in `maven-support`, not in an API module; it 
is bundled, as maven-jar-plugin does. Lost: the update and checksum policy, the 
local copy of the metadata, and the distinction resolver makes between a 
missing file and a failed transfer beyond `Optional.empty()`.
   - `Transport` has no existence check. Whether a release file exists is now 
read from its `.sha1`, so a repository that serves artifacts without checksum 
files reports no `file-release`. The alternative was downloading every artifact 
of every version.
   - No repository layout service: `Session.getPathForRemoteArtifact` is the 
path in the local cache, not in the remote repository. The default-layout 
location is built by hand (`g/a/v/a-v[-c].ext`); the extension comes from 
`session.requireType(type).getExtension()`, or the type itself when unknown, as 
the old handler manager did.
   - `ScmManager` and `I18N` are Plexus components with no v4 injection. 
`ScmManager` is now a `BasicScmManager` holding only `SvnExeScmProvider`, the 
same provider set the old classpath had; `I18N` is replaced by 
`ResourceBundle.getBundle("doap-person")`.
   - `${project.reporting.outputDirectory}` is empty in Maven 4 unless the POM 
sets it (Maven 3 always gave `${project.build.directory}/site`); the plugin 
applies that default itself. The `basic` IT caught it as an NPE.
   - `Metadata.getVersioning().getVersions()` is immutable; the old code 
reversed it in place. The unit fixture had one version, which hid the failure 
until the real run.
   - `ProjectManager` has no DI binding in rc-7; `ProjectBuilder` and 
`TransportProvider` are bound, but their implementations cannot be built in the 
test harness (`DefaultTransportProvider` needs resolver's 
`TransporterProvider`). All three are looked up with `session.getService(...)`.
   - Interpolation: the `project` and `pom` prefixes now resolve against the 
effective `Model` (getter names match for `name`, `url`, `scm.*`, 
`developers[n].*`); `basedir` is added by hand. Anything that only 
`MavenProject` had (`${project.artifact...}`, `${project.file}`) no longer 
resolves.
   - Test harness: `maven-plugin-testing-harness` 4.0.0-beta-4 has no real 
repository session (3.5.1 had `realRepositorySession = true`), so the two tests 
that resolved plexus-utils 1.5.5 and xstream 1.1 from Central now use fixture 
POMs (`src/test/resources/unit/artifact`, reduced by hand) and a mocked 
`Session`/`ProjectBuilder`, and the release tests use a directory-backed fake 
`Transport`. The real resolution path is covered only by the smoke run above, 
not by a committed test.
   
   **User-visible changes**
   - Needs Maven 4.0.0-rc-7 or newer and Java 17; `<prerequisites>` follows 
`mavenVersion`. The `generate` goal and its writable parameters keep their 
names.
   - Release listing: repository choice, existence check and metadata handling 
differ as described above.
   - `<artifact>` builds a model with Maven 4's default POM validation instead 
of minimal validation.
   - `.github/workflows/maven-verify.yml` still carries the JDK 8 / Maven 3.9.0 
`matrix-include` entry, which cannot run a Maven 4 plugin; not touched.
   
   **Improvements:** drops `maven-plugin-api`, `maven-core`, `maven-artifact`, 
`maven-settings`, `maven-model`, `maven-model-builder`, 
`maven-repository-metadata`, `maven-resolver-api/impl/spi`, 
`maven-scm-manager-plexus`, `plexus-i18n`, `javax.inject` and the resolver test 
connectors; `XmlStreamReader` is no longer needed on the release path.
   
   **Recommendation:** port, and ask apache/maven for four things: a policy 
accessor on `RemoteRepository`, an existence check on `Transport`, a `Metadata` 
read service, and `ProjectBuilder` by coordinates that returns a `Project` for 
a repository POM. Until then a plugin that lists releases is the kind that 
loses most by moving. Release it as a 4.x line next to the 3.x one.
   
   </details>
   
   <details><summary><b>maven-ear-plugin</b>: partial</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **partial**, 
4.0.0-beta-1-SNAPSHOT (was 3.4.1-SNAPSHOT), Java 17.
   
   Verified locally: Maven 4.0.0-rc-7, JDK 21. `mvn verify` -> 48 unit tests 
before (8 classes) and 49 after, 0 failures/errors/skipped (one test added, see 
Tests). `mvn verify -Prun-its` -> before: 18/18 invoker ITs and 103/103 
`EarMojoIT` pass (45 min, run with other builds in parallel); after: 17/18 
invoker ITs pass and 103/103 `EarMojoIT` pass (13 min). The one failing IT is 
`skinny-wars-timestamp` (see Gaps); the before run is the 3.4.1 plugin under 
Maven 4. `spotless:check` clean. Released artifacts: maven-archiver 
4.0.0-beta-5, maven-filtering 4.0.0-beta-1, plugin-tools 4.0.0-beta-1. Local 
snapshot consumed: maven-mapping 4.0.0-SNAPSHOT (`agent/mvn4-api` at 1f0a2fa, 
worktree `wt-fbf-dep-mapping`, `mvn install -DskipTests`).
   
   **User-visible changes**
   - Runs only on Maven 4 (no `maven-plugin-api`, `maven-core`, 
`maven-artifact`, `javax.inject`, `maven-shared-utils`). A 3.x line has to stay 
for Maven 3 builds.
   - Goals `ear` and `generate-application-xml`, their phases and every 
parameter name are unchanged; `threadSafe` is no longer declared (v4 `@Mojo` 
has no such attribute), nor `requiresDependencyResolution` (the plugin resolves 
`PathScope.TEST_RUNTIME` itself through `DependencyResolver`).
   - `earSourceDirectory` default is `${project.basedir}/src/main/application` 
(`${basedir}` is not evaluated in v4, the directory was silently ignored), and 
the `description` default is `${project.model.description}`.
   - `@{version}@` (the default `outputFileNameMapping`) of a SNAPSHOT 
dependency expands to `1.0-SNAPSHOT`, no longer to the timestamped 
`1.0-20150825.210557-91`; the documented "timestamp postfix" in 
customize-file-name-mapping is not reproducible (see Gaps). EAR entry names and 
the Class-Path of skinny modules change accordingly for SNAPSHOT dependencies.
   - maven-mapping tokens (`outputFileNameMapping`): the documented ones 
(`groupId`, `artifactId`, `version`, `baseVersion`, `dashClassifier?`, 
`extension`) are unaffected. The v4 port drops the `ArtifactHandler` value 
source and `api.Artifact` has no `type`/`scope`; because the plugin passes the 
`Dependency`, `@{type}@` now prints the `Type` object's `toString()` (not 
`ejb`) and `@{scope}@` prints `COMPILE` (not `compile`), and `@{packaging}@`, 
`@{language}@`, `@{file}@` stay literal in the file name. None of these is 
documented or used in the repo's poms/ITs.
   - Free-form parameters `artifactTypeMappings`, `jboss`, `security`, 
`envEntries`, `ejbRefs`, `resourceRefs` are `XmlNode` instead of 
`PlexusConfiguration`; the XML users write is unchanged.
   - Modules are still typed by the dependency type: 
`Dependency.getType().id()` is the declared string (`ejb`, `war`, `rar`, `sar`, 
`har`, `par`, `wsr`, `app-client`, `ejb-client`, `test-jar`, 
`jboss-sar`/`-har`/`-par`, custom types through `artifactTypeMappings`), so the 
type to module mapping works and is covered by 103 `EarMojoIT` projects. `ejb`, 
`ejb-client`, `war`, `ear`, `test-jar` are registered types in rc-7; the rest 
fall back to the legacy handler (extension = type) and resolve fine. The v4 
`Type` replaces the `ArtifactHandler` for `includesDependencies`/extension 
only; the ear-specific mapping (`EarModuleFactory`, 
`ArtifactTypeMappingService`) stays in the plugin, nothing in v4 replaces it.
   - Public Java API: `EarModule.getArtifact()` returns the new 
`util.ResolvedArtifact` (dependency + resolved `Path`; v4 `Dependency` carries 
no file) instead of `Artifact`; module constructors, `ArtifactRepository`, 
`EarExecutionContext` follow; `resolveArtifact` no longer throws the checked 
`MojoFailureException`, `InvalidJavaEEVersion` extends the unchecked 
`MojoException`; `ArtifactTypeMappingService.configure` takes the new 
`util.XmlConfig` (a read-only view over `XmlNode`); 
`EarMavenArchiver.getManifest` takes `api.Session/Project` and the deprecated 
`getManifest(MavenProject, config)` overload is removed; `EarMojo` has no 
constructor (archivers are created inside; `ArchiverManager` replaced by `new 
ZipUnArchiver()`).
   - New `Providers` (`@Provides` `ProjectManager`, `BuildContext`) for 
`MavenFileFilter`; the ear artifact is attached with 
`ProjectManager.attachArtifact(project, project.getMainArtifact(), ear)` or a 
produced artifact of type `ear` for a classifier.
   
   **Gaps**
   - `skinny-wars-timestamp` IT fails (only after-failure): v4 gives the 
resolved SNAPSHOT `Dependency` version `1.0-SNAPSHOT` and a `-SNAPSHOT` 
local-repo file name; `session.resolveArtifact` returns the same. The 
timestamped version is unreachable through the API, so the IT's expectations 
(`eartest-jar-sample-one-1.0-20150825.210557-91.jar` in Class-Path, timestamped 
jar removed from the WAR built by the 3.x war plugin) cannot hold. With a v4 
war plugin both sides use `-SNAPSHOT` and the original-file-name lookup 
matches; only mixed 3.x-war/4.x-ear builds leave the duplicate jar in 
`WEB-INF/lib`. IT left red on purpose, not edited.
   - `DependencyResolver` ignores `Type.isIncludesDependencies()` (`war`, 
`ear`, `rar`) although the session has `FatArtifactTraverser`: the war's 
transitives appear in the result, and an artifact reachable by several paths is 
listed only below the nearest one (`skinny-wars-javaee5` and `project-089..096` 
failed with it). Worked around in `AbstractEarMojo.resolveProjectArtifacts`: a 
RESOLVE tree plus a verbose COLLECT tree; an artifact is kept only if reachable 
without passing through an `includesDependencies` node (a reachable winner's 
subtree counts). Approximation: a version conflict won by the fat path is not 
re-mediated.
   - `XmlNode` mojo parameters lose XML attributes 
(`DefaultBeanConfigurator.XmlConverter` builds the node with `null` attributes; 
same on core master): `artifactTypeMapping type= mapping=`, `security-role id`, 
`loader-repository class`. Worked around by reading those elements from the 
injected `MojoExecution.getConfiguration()` (model `XmlNode`, attributes 
intact); values are model-interpolated only, `${session.*}`-style expressions 
are not evaluated. `PlexusConfiguration` parameters cannot work at all ("Cannot 
create instance of interface"): core does not export 
`org.codehaus.plexus.configuration` to plugin realms, `@Mojo(configurator = 
"basic")` does not help.
   - `Session` has no build start time; `deleteOutdatedResources` uses the JVM 
start time, so under a long-lived JVM (mvnd) stale files from an earlier build 
in the same daemon are not deleted.
   - Mojo failure vs error is lost (`MojoException` only), so 
`MojoFailureException` paths (unknown artifact, missing candidate) now report 
as errors.
   - `META-INF/plexus/components.xml` (ear `ArtifactHandler` and 
`LifecycleMapping`) is kept untouched and not exercised: Maven 4 core has 
built-in `ear` type and `ear` lifecycle mapping 
(`EarLifecycleMappingProvider`), which the ITs use; a plugin-provided packaging 
needs the Plexus components in rc-7.
   - System-scope dependencies: `PathScope.TEST_RUNTIME` has no `SYSTEM` scope 
in rc-7, so they are not part of the module set; not covered by any IT.
   
   **Tests:** all 48 unit tests kept. `AbstractEarTestBase` builds 
`ResolvedArtifact` over a new `stub/DependencyStub` (implements 
`api.Dependency`); removed `stub/ArtifactHandlerTestStub` (v3 
`ArtifactHandler`, unused now). `ArtifactTypeMappingServiceTest` builds 
`XmlNode` instead of `XmlPlexusConfiguration`; its 
`testConfigWithSameCustomType` never populated the second mapping (it set the 
attributes on the first element twice), so it only exercised the 
missing-attribute path: kept as is and 
`testConfigWithSameCustomTypeRegisteredTwice` added for the real duplicate (49 
tests). `AbstractEarPluginIT` uses plexus-utils `FileUtils`. No IT source 
changed.
   
   **Improvements:** drops `maven-plugin-api`, `maven-core`, `maven-artifact`, 
`maven-plugin-annotations`, `javax.inject`, `maven-shared-utils`; adds 
`maven-api-core/di/annotations/model/xml` (provided), `plexus-build-api` and 
`org.eclipse.sisu.plexus` (needed at runtime by `ThreadBuildContext`, 
`AbstractLogEnabled`; `dependency:analyze` ignore entry added).
   
   **Recommendation:** not mergeable as is. Port for Maven 4 and keep a 3.x 
line, but only after the core gaps are filed: `includesDependencies` not 
honoured by the API resolver, `XmlNode` parameter conversion dropping 
attributes, no snapshot timestamp version and no session start time in the API. 
The ear plugin itself ports with workarounds that restore behaviour for all 103 
`EarMojoIT` cases and 17 of 18 invoker ITs; `skinny-wars-timestamp` is the one 
documented behaviour that cannot be kept.
   
   </details>
   
   <details><summary><b>maven-ejb-plugin</b>: ported</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **ported**, 
4.0.0-beta-1-SNAPSHOT (was 3.3.1-SNAPSHOT), Java 17.
   
   Verified locally: Maven 4.0.0-rc-7, JDK 21. `mvn verify` → 36 tests before 
(19 EjbMojoTest, 10 EjbHelperTest, 7 IncludesExcludesTest) and 36 after, 0 
failures/errors/skipped. `mvn verify -Prun-its` → 9/9 invoker ITs pass before 
(4m58s) and after; `spotless:check` clean. Released artifacts only, no local 
snapshots: maven-archiver 4.0.0-beta-5, maven-filtering 4.0.0-beta-1, 
maven-plugin-plugin 4.0.0-beta-1, maven-testing 4.0.0-rc-7.
   
   **User-visible changes**
   - Runs only on Maven 4 (no `javax.inject`, `maven-plugin-api`, `maven-core`, 
`maven-artifact`, `maven-model`, `maven-settings`, sisu annotations). A 3.x 
line has to stay for Maven 3 builds.
   - Goal `ejb`, phase `package` and every parameter (`classifier`, 
`clientClassifier`, `ejbJar`, `ejbVersion`, `generateClient`, 
`clientIncludes/Excludes`, `excludes`, `archive`, filtering options, 
`outputTimestamp`) are unchanged; `threadSafe` is no longer declared (v4 
`@Mojo` has no such attribute).
   - Public API: `EjbMojo.getProject()` now returns 
`org.apache.maven.api.Project` (was `MavenProject`); `validateEjbVersion` 
throws the unchecked `MojoException` (was checked `MojoExecutionException`). 
`EjbHelper` is unchanged.
   - Main jar is attached via `ProjectManager.attachArtifact(project, 
project.getMainArtifact(), path)`; classified jar and client jar via 
`session.createProducedArtifact(..., type "ejb" / "ejb-client")`. The old 
unreachable `FIXME` branch for a null client classifier did the same call as 
the valid branch and is merged into it.
   - Maven 4 prints the "You have to use a classifier ..." failure without the 
trailing ` -> [Help 1]`, so the IT `mejb-93` now matches the message without it 
(it still asserts the same behaviour: a second execution without classifier 
fails).
   - New `Providers` class (`@Provides`) supplies `ProjectManager` and 
`BuildContext` (required by `DefaultMavenFileFilter` 4.0.0-beta-1).
   
   **Gaps**
   - `org.eclipse.sisu:org.eclipse.sisu.plexus` must be a compile dependency: 
`ThreadBuildContext` (plexus-build-api 0.0.7) extends 
`org.codehaus.plexus.logging.AbstractLogEnabled`, which a v4 plugin realm does 
not provide. Without it all 7 ITs failed with `NoClassDefFoundError: 
org/codehaus/plexus/logging/AbstractLogEnabled`. maven-resources-plugin master 
carries the same dependency.
   - `@Mojo(requiresDependencyResolution = RUNTIME)` has no usable v4 
equivalent with maven-plugin-plugin 4.0.0-beta-1 
(`dependencyResolutionPathScopes` fails descriptor generation: "Method: 
'dependencyResolutionPathScopes' not found in class MojoAnnotationContent"). 
Dropped; `MavenArchiver.getManifest` resolves `MAIN_RUNTIME` itself through 
`DependencyResolver`, and the `manifest-content` IT passes.
   - The v3 harness (`AbstractMojoTestCase`, `MavenProject` stubs) has no v4 
counterpart.
   
   **Tests:** `EjbMojoTest` rewritten on JUnit 5 with `maven-testing` 
(`ProjectStub`, `SessionMock`), `@TempDir` and a mocked `ProjectManager`; all 
18 original scenarios kept with the same assertions, one lookup test moved to 
`@MojoTest`/`@InjectMojo` (resource renamed `plugin-config.xml` to `pom.xml`), 
and two attach assertions added (`verify` on `ProjectManager`/`Session` for the 
default and classified+client cases). Removed and replaced: 
`stub/MavenProjectBasicStub`, `MavenProjectBuildStub`, 
`MavenProjectResourcesStub`, `ModelStub` (v3 `MavenProject` subclasses; 
replaced by the nested `TestProject`). `vintage-engine` and 
`maven-plugin-testing-harness` 3.5.1 dropped. `EjbMojo` fields are set by 
reflection in these tests, as before.
   
   **Improvements:** drops `javax.inject`, `maven-plugin-api`, `maven-core`, 
`maven-artifact`, `maven-model`, `maven-settings`, `maven-shared-utils`, 
`plexus-utils`, `org.eclipse.sisu.inject`, JUnit vintage, the v3 testing 
harness.
   
   **Recommendation:** port for Maven 4; keep a 3.x line for Maven 3 users. 
maven-ear-plugin's pom only lists maven-ejb-plugin as an `extraArtifact` for 
its ITs (`mavenEjbPluginVersion`), so it is not a compile-time consumer; its 
ITs that resolve the ejb plugin would need a 4.x version together with Maven 4.
   
   </details>
   
   <details><summary><b>maven-gpg-plugin</b>: partial</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **partial**, 
4.0.0-beta-1-SNAPSHOT, Java 17. All three goals (`sign`, 
`sign-and-deploy-file`, `sign-deployed`) ported and exercised by the ITs; one 
behaviour cannot be ported with the API (encrypted settings passphrases, see 
Gaps). No test or IT removed.
   
   Verified locally: Maven 4.0.0-rc-7, JDK 21. `mvn -B -ntp verify`: 10 tests, 
0 failures, 1 skipped (`BcSignerTest` 6, `GpgVersionTest` 3, 
`GpgVersionConsumerTest` 1), before and after. `-Prun-its` with the Bouncy 
Castle signer (`bc-integration-tests` plus failsafe `Bc*IT`): invoker 13 of 13 
passed and `BcSignArtifactIT` 4 of 4, before and after. The 
`gpg-integration-tests` execution and `GpgSignArtifactIT` could not be 
measured: the system gpg 2.5 fails with "can't connect to the gpg-agent: File 
name too long" (macOS socket path limit; the worktree path is too long), which 
gave 1 of 13 before, so for the comparison that execution was switched off in a 
scratch copy of the pom in both runs. The `gpg` signer path is therefore not 
exercised after the port beyond compilation. Spotless clean.
   
   **v4 routes**
   - Attach: `MavenProjectHelper.attachArtifact(project, type, classifier, 
file)` becomes `ProjectManager.attachArtifact(Project, ProducedArtifact, Path)` 
with `session.createProducedArtifact(g, a, v, classifier, extension + ".asc", 
null)` (the 6-argument factory, because the short `attachArtifact` overloads 
cannot carry a classifier). `FilesCollector` reads 
`ProjectManager.getPath/getAttachedArtifacts` and `ArtifactManager.getPath`.
   - `sign-and-deploy-file` outside a project: yes. Same shape as 
`maven-deploy-plugin` 4.0.0-beta-3 `DeployFileMojo` (`projectRequired = 
false`): artifacts from `session.createProducedArtifact`, paths via 
`ArtifactManager.setPath`, deploy via `ArtifactDeployer` with 
`ArtifactDeployerRequest` (its `retryFailedDeploymentCount` replaces the 
hand-written retry loop), repository from `session.createRemoteRepository(id, 
url)`, POM read/generated with `ModelXmlFactory`. Signing itself has no API and 
stays in `GpgSigner`/`BcSigner`.
   - `sign-deployed`: 
`session.withLocalRepository(session.createLocalRepository(tmp))` for the 
private repo, `resolveArtifacts(coordinates, repos)`, `ArtifactDeployer` for 
the `.asc` files.
   
   **Public API changes**
   - Mojos implement `org.apache.maven.api.plugin.Mojo`; 
`MojoExecutionException`/`MojoFailureException` become the unchecked 
`MojoException` in all public signatures (`AbstractGpgSigner`, `GpgSigner`, 
`BcSigner`, `GpgVersionParser`, `FilesCollector`).
   - `BcSigner(Session, ...)` and its `Loader` methods take 
`org.apache.maven.api.Session` instead of the aether session; 
`FilesCollector(Session, Project, String[], Log)` (was `MavenProject, String[], 
Log`); `AbstractGpgMojo.getPassphrase(Project)`.
   - `ArtifactCollectorSPI.collectArtifacts(Session, RemoteRepository)` now 
uses `org.apache.maven.api.Artifact/RemoteRepository/Session`: an SPI break for 
any implementor.
   - The `settings` parameter (`${settings}`) and the injected 
`SettingsDecrypter` are gone; `session.getSettings()` is used.
   - Env variables (`env.MAVEN_GPG_*`) are read from the session user then 
system properties (`BcSigner.getEnv`), replacing 
`RepositorySystemSession.getConfigProperties()`.
   
   **Gaps**
   - Encrypted passphrases in `settings.xml`: rc-7 has no decrypt service in 
any `maven-api-*` module (`SettingsDecrypter` exists only in compat 
`maven-settings-builder`, and `maven-impl` never calls it). 
`gpg.passphraseServerId` values that look encrypted (`{...}`) now fail with an 
explicit `MojoException` instead of being signed with as cipher text; plain 
passphrases still work (IT `sign-with-passphase-from-maven-settings` passes). 
Needs a settings-decrypt service in `maven-api-core` to be closed.
   - The "old way" passphrase-from-project-properties read no longer copies the 
found value onto the reactor root project (`Project.getModel().getProperties()` 
is immutable).
   - `ModelValidator` strict validation of the coordinates in 
`sign-and-deploy-file` has no API equivalent; replaced by a local check 
(groupId/artifactId `[A-Za-z0-9_.-]+`, version without path or whitespace 
characters, packaging non-blank), which is looser than the model validator.
   - `ArtifactHandlerManager` replaced by `TypeRegistry.lookup(packaging)`; 
unknown types fall back to extension = type, as before.
   - Mojo constructor injection does not work with the generated `MojoFactory` 
(`NoSuchMethodError: SignDeployedMojo.<init>()`): `SignDeployedMojo` uses field 
injection, `@Inject @Nullable Map<String, ArtifactCollectorSPI>` (an empty map 
otherwise fails to inject).
   - `BcSignerTest` built an aether session with `maven-resolver-impl`; it now 
uses a `java.lang.reflect.Proxy` over `Session` that answers only the two 
property maps (no new test dependency, which would need a pgpverify keys-map 
entry).
   - `<proc>none</proc>` removed from the compiler configuration so the api.di 
index is generated.
   - `plexus-utils` (`FileUtils`, `SelectorUtils`, `Os`, `cli.*`, 
`CachingOutputStream`) is not a Maven API and stays.
   
   **User-visible changes**
   - Requires Maven 4; Java 17; `<prerequisites>` follows `mavenVersion`.
   - Failure text `MojoFailureException: Do not store passphrase...` is now 
`MojoException: ...` (IT `sign-release-best-practices-fail` updated).
   - Encrypted server passphrase: explicit failure, see Gaps. 
`retryFailedDeploymentCount` log lines ("Retrying deployment attempt") no 
longer come from the plugin.
   - `maven-resolver-impl` test dependency and the `resolverVersion` property 
removed.
   
   **Improvements:** drops `maven-core`, `maven-plugin-api`, `maven-artifact`, 
`maven-model`, `maven-model-builder`, `maven-settings`, 
`maven-settings-builder`, `maven-resolver-api/util`, 
`maven-plugin-annotations`, `javax.inject`.
   
   **Recommendation:** port is viable; do not merge until the settings-decrypt 
gap is decided (file against apache/maven), and run the `gpg` signer ITs on a 
machine with a short checkout path.
   
   </details>
   
   <details><summary><b>maven-help-plugin</b>: ported</summary>
   
   Branch `agent/mvn4-api`; PR not opened yet. Status: **ported**, 
4.0.0-beta-1-SNAPSHOT (was 3.5.3-SNAPSHOT), Java 17. Two goals are degraded, 
see Gaps.
   
   Verified locally: Maven 4.0.0-rc-7, JDK 21. `mvn verify` before → 30 tests, 
0 failed, 0 skipped; after → 61 tests, 0 failed, 0 skipped. `mvn verify 
-Prun-its` before → 34 passed, 0 failed, 2 skipped (12m27s); after → 36 passed, 
0 failed, 0 skipped (18m03s, run on a copy of the tree); 
`describe-cmd-with-goal-report` failed on its first attempt (the report check 
logged `Couldn't identify if this goal is a report goal: 
org/apache/maven/plugin/AbstractMojo`, cause not isolated) and passed on the 
invoker retry. `spotless:check` clean. No local snapshots consumed, released 
artifacts only.
   
   **User-visible changes**
   - All 11 goals are `org.apache.maven.api.plugin.Mojo`s; `session`, 
`project`, `Log` and the services are `@Inject`ed. Goal names, phases and 
parameter names/properties are unchanged; `output` is now a `Path` (same XML 
syntax). The plugin no longer loads under Maven 3: a 3.x line has to stay.
   - `evaluate`: the expression evaluator of Maven 3 is gone. The new one 
(`ExpressionEvaluator`) handles `project`, `session`, `settings`, `mojo`, 
`plugin`, `localRepository`, `reactorProjects`, `basedir`, `rootDirectory`, 
`env.X`, then project properties, session properties and system properties, 
through the public getters of the API objects (`a.b.c`, `list[0]`, `map(key)`). 
`${project.x}` falls back to the model when `Project` has no getter, so 
`project.name` and `project.properties` work. Objects that are not a model, 
settings or scalar are written by `XmlRenderer` (bean, list, map), not by 
XStream, so the element order of such output is alphabetical instead of field 
order. Interactive mode uses the `Prompter` service instead of `InputHandler`.
   - `effective-pom`: properties are written sorted (the IT 
`effective-pom_properties` expected the reversed hash order of Maven 4 with the 
old plugin; it now expects the sorted order on every Maven version). Verbose 
location comments go through `XmlWriterRequest.inputLocationFormatter`.
   - `active-profiles`: the source of a POM profile is the `g:a:v` of the POM 
in the parent chain that declares it (from `getDeclaredActiveProfiles`), 
settings profiles are listed once as `external`. The ITs `active-profiles` and 
`active-profiles_multimodule` pass.
   - `list-lifecycle-phases`, `describe -Dcmd=<phase>`: phases are the Maven 4 
ones (`before:compile`, `after:resources`, ...). `describe 
-Dcmd=process-resources` still works through `Lifecycle.aliases()`.
   - `list-packaging`, `list-dependency-types`: only the ids Maven itself 
defines are listed (see Gaps).
   - `describe`: plugin `groupId:artifactId[:version]` works through the plugin 
jar and its `META-INF/maven/plugin.xml`; `-Dplugin=<prefix>` and 
`-Dcmd=<prefix>:<goal>` work for the plugins of the project and for 
`maven-<prefix>-plugin` / `<prefix>-maven-plugin` in the plugin groups of 
settings, `org.apache.maven.plugins` and `org.codehaus.mojo`.
   - The two ITs `evaluate-model-collections` and `evaluate-settings-servers` 
were skipped on Maven 4 (`invoker.maven.version = 4-`, XStream could not 
serialise immutable maps); they now run and pass, the skip line is removed.
   
   **Gaps**
   - No v4 route, goal `describe` only: plugin prefix resolution from the 
repositories' group metadata (`MojoDescriptorCreator.findPluginForPrefix`, 
`PluginPrefixResolver`). The prefix heuristic above cannot find a plugin with a 
non-conventional artifactId that the project does not declare. No plugin 
version resolver either: a missing version is the one of the project's 
`build/plugins` or `pluginManagement`, else the highest non-snapshot of the 
version range. Relocations of the plugin POM are not followed 
(`ArtifactResolver` does not read the descriptor).
   - No v4 route, goals `list-packaging` and `list-dependency-types`: 
`PackagingRegistry` and `TypeRegistry` only look up by id 
(`ExtensibleEnumRegistry` has no listing), and the legacy handlers come from 
Sisu components. The goals probe the constants of `org.apache.maven.api.Type` 
plus `ejb`, `ejb-client`, `war`, `ear`, `rar`, `par`, `sources`, 
`test-sources`, and the packagings `pom, jar, maven-plugin, ejb, ejb3, war, 
ear, rar`. A packaging or type that a third-party extension registers is not 
listed.
   - `describe` with a plugin whose POM Maven 4 rejects (the IT uses 
maven-help-plugin:2.0): `ProjectBuilderRequest` has no validation level, so the 
name is read from the POM file and the report-goal check falls back to the 
runtime dependencies.
   - v4 `MojoDescriptor`/`Parameter` drop the `<configuration>` element of a 
Maven 3 `plugin.xml` (default value, expression). `describe` reads it with its 
own DOM pass so that "Default" and "User property" still show for Maven 3 
plugins.
   - `evaluate` cannot evaluate what Maven 3 evaluated through 
`PluginParameterExpressionEvaluator` and the session internals: anything that 
is not reachable through a public getter or method of the API objects (for 
example the plugin context). Unmeasured beyond the expressions in the ITs and 
`ExpressionEvaluatorTest`.
   - `active-profiles`: Maven 4 gives no per-model activation record, only 
`getDeclaredActiveProfiles()` per project, so the source is the POM in the 
parent chain that declares the active profile.
   
   Tests: `AbstractHelpMojoTest` now tests `parseCoordinates` (same four 
cases); in `DescribeMojoTest` the three lookup tests that mocked 
`MojoDescriptorCreator`/`PluginVersionResolver`/`MavenPluginManager` are 
replaced by lookups on a generated plugin jar (prefix with and without version, 
GAV); the `describeCommand` tests run on mocked 
`LifecycleRegistry`/`Packaging`. No test was deleted; new: 
`EffectivePomMojoTest`, `EffectiveSettingsMojoTest`, `ExpressionEvaluatorTest`, 
`ListMojosTest`.
   
   **Improvements:** drops `maven-artifact`, `maven-core`, `maven-model`, 
`maven-model-builder`, `maven-plugin-api`, `maven-settings`, 
`maven-resolver-api`, `javax.inject`, `org.eclipse.sisu.plexus`, 
`maven-plugin-annotations`, `maven-shared-utils`, `plexus-interactivity-api` 
and `xstream`. `plexus-utils` (needed at runtime by `HtmlToPlainTextConverter`, 
whose own dependencies are excluded), `plexus-xml`, `jdom2`, 
`maven-reporting-api` 4.0.0 (only the `MavenReport` type check) and 
`maven-plugin-tools-generators` stay. Adds `maven-api-core/di/annotations` and 
`maven-xml` (provided).
   
   **Recommendation:** port for Maven 4 and keep a 3.x line for Maven 3. 
Upstream follow-ups worth filing: a listing method on `ExtensibleEnumRegistry`; 
a plugin-prefix and plugin-version resolution service in the API; 
`MojoDescriptor` keeping the v3 `<configuration>` defaults; a validation-level 
option on `ProjectBuilderRequest`; a public expression evaluator for plugins.
   
   </details>
   
   <details><summary><b>maven-invoker-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 verify` with Maven 4.0.0-rc-7, JDK 21 → 67 unit tests 
before and after, 0 failures, 0 skipped; spotless clean. `-Prun-its` (92 IT 
projects): before, the 30 min time-box hit after 45 ITs (all 45 passed, none 
failed); after, the same 45 ITs ran in 1770 s and all pass (44 at first, 
`staging-pom` after the fix below), plus 26 more selected by the code they 
touch (`-Dinvoker.test=` list of settings-*, script-*, local-repo-*, staging-*, 
install-*, invoker-report, ...): 24 pass, 2 fail 
(`MINVOKER-377-install-ignore-split-repo`, `invoker-report`, see Gaps). Not 
run, before or after: 22 ITs (MINVOKER-196, -288-failed-setup-verify, -289, 
-294, -330, exec-timeout-mojo-level, fail-build-with-verify*, fail-ignore*, 
fail-noprojects_verify, invocation-cmdline-exclude, invocation-debug, 
invocation-group-properties, invocation-reactor-indirect, invocation-spaces, 
multiple-pre-post-build, project-cloning-reactor, rerun-build, 
rerun-build-invoker-test-in-config, script-strea
 mLogs-false). Not measured: running the ported plugin under Maven 3; heavy 
machine load (load average >100) makes the IT timings unreliable.
   
   Uses `maven-api-core`/`-di`/`-annotations`/`-model`/`-settings` 4.0.0-rc-7 
(provided), plugin-tools 4.0.0-beta-3, and the local snapshots 
`maven-reporting-api` and `maven-reporting-impl` 5.0.0-SNAPSHOT (agent/mvn4-api 
branch of reporting-impl, already in the local repository, not rebuilt here). 
maven-invoker 3.3.0 and maven-script-interpreter 1.9 use no Maven API and are 
unchanged.
   
   **v4 route for install into an alternate local repository** 
(`invoker:install`): 
`Session.withLocalRepository(session.createLocalRepository(path))` gives a 
session bound to the staging repo; 
`DependencyResolver.resolve(DependencyResolverRequest{project|root dependency, 
PathScope})` returns `getDependencies()` (Dependency to Path) for the 
transitive closure; POMs and their parent chains come from 
`session.resolveArtifact(createArtifactCoordinates(g, a, v, "pom"), repos)`; 
`ProjectManager.getRemoteProjectRepositories/getRemotePluginRepositories` 
supply the repositories; `altSession.installArtifacts(...)` writes them. Scope 
`runtime`/`compile`/`test` maps to 
`PathScope.MAIN_RUNTIME`/`MAIN_COMPILE`/`TEST_RUNTIME`. Two traps, both hit by 
ITs:
   - `Session.setArtifactPath(ProducedArtifact, Path)` rewrites the file of 
every reactor project artifact with the same id and throws 
`UnsupportedOperationException: transformed artifact file cannot be set` for 
the project's own (transformed) POM. Reactor artifacts must be installed as 
they are (`Project.getArtifacts()` + `ProjectManager.getAttachedArtifacts()`, 
the file travels inside the artifact); `setArtifactPath` only for downloaded 
ones.
   - `Project.getParent()` returns only reactor parents, unlike 
`MavenProject.getParent()`; the parent chain has to be walked through 
`project.getModel().getParent()` and resolved (IT `staging-pom` caught it).
   
   **Script-visible bindings** (`ScriptRunner` globals, 
maven-script-interpreter): none of them carries a Maven type, so no binding 
changes type. `basedir` (script dir, `File`), `context`, `scriptFile`, 
`logger`, `localRepositoryPath` (`File`), `mavenVersion` (`String`) and 
`scriptVariables` are as before. Value changes: `localRepositoryPath` default 
is now `session.getLocalRepository().getPath()` (follows `-Dmaven.repo.local`; 
was `${settings.localRepository}`); `mavenVersion` with no `mavenHome` is 
`session.getMavenVersion()`. What does change is the script class path: scripts 
used to see the Maven 3 plugin realm, so 
`org.apache.maven.plugin.MojoExecutionException` (IT 
`settings-merge/postbuild.groovy`, now throws `IllegalStateException`), 
`MavenProject` and friends resolved; in a v4 plugin realm they do not (`unable 
to resolve class org.apache.maven.plugin.MojoExecutionException`). With 
`addTestClassPath` the test class path is resolved by 
`session.resolveDependencies(project, Pat
 hScope.TEST_RUNTIME)` plus the project's test and main output directories, 
minus the plugin's own artifact and dependencies.
   
   **Public API changes**
   - Plugin runs on Maven 4 only (v4 `Mojo`, `@Inject`, `@Mojo(defaultPhase = 
"...")`); all mojos throw the unchecked `MojoException`. `MojoFailureException` 
(BUILD FAILURE) and `MojoExecutionException` (error) are no longer 
distinguishable.
   - Goals `install`, `run`, `integration-test`, `verify`, `report` and their 
parameters keep names and properties. `requiresDependencyResolution = TEST` and 
`threadSafe = true` are gone (no v4 attribute); `install` and `run` resolve 
what they need themselves.
   - Defaults that changed: `localRepositoryPath` (install and run) has no 
expression default; it falls back to the session's local repository. 
`projectsDirectory` default is `${project.basedir}/src/it/` because 
`${basedir}` is not evaluated in v4 (it stays literal and `run` then reports 
"No projects were selected"). `invoker.install.scope` also accepts the v4 path 
scope ids.
   - `AbstractInvokerMojo`/`InstallMojo` constructors are gone (`Invoker`, 
`SettingsBuilder`, `ToolchainManager`, `MavenProject`, `MavenSession` are no 
longer injected; `DefaultInvoker` is instantiated, v4 services come from 
`session.getService`). `InvokerReport` no longer takes an `I18N`; it reads the 
`invoker-report` bundle directly.
   - Interpolation (`CompositeMap`) now reads `project.*`/`pom.*` from the 
effective `Model` (plus `basedir`, `file`): expressions that hit 
`MavenProject`-only getters (`project.artifact`, `project.file` as `File`, 
`project.compileSourceRoots`) no longer resolve.
   - `mergeUserSettings`: the merge is hand-written (`mergeSettings` in 
`AbstractInvokerMojo`), dominant entries win by id, because the v4 API has no 
`SettingsUtils.merge`; the MINVOKER-133 `sourceLevelSet` reset has no 
counterpart (immutable settings model).
   - POM scanning also follows `<subprojects>`, which v3 could not read (not 
exercised by an IT).
   
   **Gaps**
   - `invoker:install` cannot pin the resolver config of the staging 
repository. The v3 code cloned the repository session with 
`aether.enhancedLocalRepository.split=false` (MINVOKER-377); 
`Session.withLocalRepository` inherits the outer build's config and offers no 
way to override it. IT `MINVOKER-377-install-ignore-split-repo` fails 
(artifacts land under `installed/`, not the flat path). Not worked around: 
copying files and writing `maven-metadata-local.xml` by hand would be inventing 
an installer. The forked builds still get 
`-Daether.enhancedLocalRepository.split=false`, so `run` is unaffected.
   - Report goal: **blocked**. It compiles against the local v4 
`AbstractMavenReport` (reporting-impl 5.0.0-SNAPSHOT) but cannot run. 
Standalone, `mvn 
org.apache.maven.plugins:maven-invoker-plugin:4.0.0-beta-1-SNAPSHOT:report` 
fails with `A required class was missing ... report: 
org/apache/maven/execution/MavenSession` (`NoClassDefFoundError` at 
`LegacyMavenBridge.<init>` from `AbstractMavenReport.getSiteTool`, because the 
doxia-tools/site-tool side still needs maven-core classes that a v4 plugin 
realm does not have). Through `mvn site`, maven-site-plugin 3.22.0 fails with 
`Failed to get report for org.apache.maven.plugins:maven-invoker-plugin: Unable 
to lookup Mojo: Cannot cast 
org.apache.maven.plugins.invoker.InvokerReportFactory to 
org.apache.maven.plugin.Mojo` (IT `invoker-report`). Needs doxia-sitetools, 
site plugin and reporting-exec on v4 first.
   - No v4 `Mojo`/`Plugin` API for "the plugin realm's artifacts" 
(`plugin.artifacts`): approximated with 
`MojoExecution.getPlugin().getArtifact()/getDependencies()` and 
`Session.getArtifactPath`.
   - v4 dependency resolution omits the project's own output directories, added 
by hand for `addTestClassPath`.
   - No removed tests; test changes: mocks of 
`MavenProject`/`MavenSession`/`Settings` replaced by mocks of 
`Project`/`Session`/`Settings`, constructors without arguments, 
`InterpolatorUtils` takes a `Map`. IT `settings-merge` script changed as above.
   
   **User-visible changes**
   - Maven 3 users stay on 3.x; the 4.x line needs Maven 4.
   - IT scripts (Groovy/BeanShell) and `invoker.properties` keep working unless 
they touch Maven 3 API classes (see bindings); `${project.*}` filtering keeps 
working for model properties.
   - `invoker:report`/site integration does not work on the 4.x line yet; 
`invoker:verify` and the `invoker-reports` XML are unchanged.
   - Split local repository layouts of the invoking build are not neutralised 
by `invoker:install` (MINVOKER-377 regression).
   
   **Improvements:** drops `maven-core`, `maven-model`, `maven-plugin-api`, 
`maven-artifact`, `maven-settings`, `maven-settings-builder`, 
`maven-resolver-api`/`-util`, `maven-plugin-annotations`, `javax.inject`, 
`plexus-i18n` and `sisu-maven-plugin`; the install logic no longer talks to 
`RepositorySystem`/`RepositoryUtils`/`ProjectArtifact`. 
`<prerequisites><maven>` follows `${mavenVersion}`.
   
   **Recommendation:** port the run, install and verify goals as a 4.x line 
once MINVOKER-377 has an answer (a Session-level way to set resolver config, or 
a documented flat-layout install); keep the report goal on 3.x until the 
reporting chain is on v4 (then only `InvokerReport` and the renderer need 
touching). Scope: the 22 unrun ITs should be run before any merge.
   
   </details>
   
   <details><summary><b>maven-jarsigner-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 → 51 tests 
before, 52 after (one added for the proxy path), 0 failures, 0 skipped; `mvn 
verify -Prun-its` → 9 of 9 ITs pass before and after; `spotless:check` clean. 
Smoke runs outside the ITs on rc-7 (scratch project, not committed): toolchain 
selected through maven-toolchains-plugin 3.2.0, active proxy passed to 
jarsigner (offline run), `storepass`/`keypass` encrypted in the legacy `{...}` 
form with a `settings-security.xml` master password. Not exercised: the 
new-format `settings-security4.xml`, the `gpg-agent`, `pinentry-prompt` and 
`system-property` master sources, Windows.
   
   **Public API changes**
   - `AbstractJarsignerMojo` implements `org.apache.maven.api.plugin.Mojo` 
instead of extending `AbstractMojo`; `execute()` and the protected hooks throw 
`MojoException` instead of `MojoExecutionException`. The protected constructor 
taking `JarSigner`, `ToolchainManager` and `SecDispatcher` is gone; the mojos 
get a `DefaultJarSigner` and their services injected.
   - `@Parameter` types `File` → `Path` for `archive`, `archiveDirectory`, 
`workingDirectory` and `certchain`. `project`, `settings` and `session` are no 
longer parameters.
   - `getLog()` returns `org.apache.maven.api.plugin.Log`.
   - New public `ToolchainAdapter` (see Gaps), package-private 
`SecDispatchers`; `META-INF/plexus/components.xml` deleted.
   - `maven-jarsigner` 3.1.0 is unchanged. It uses no Maven API, so it needed 
no port.
   
   **Gaps**
   - No service to decrypt a configuration value. The plugin decrypts 
`storepass` and `keypass` itself, and Maven's own decryptor is wired inside 
`maven-impl` (`DefaultSettingsBuilder`), not reachable from a plugin. 
`SecDispatchers` rebuilds it as `ApiRunner$SecDispatcherBindings` does, from 
`internal` classes of plexus-sec-dispatcher 4.2.0 (`AESGCMNoPadding`, 
`MasterDispatcher`, `LegacyDispatcher`, `DefaultSecDispatcher`), reading 
`${user.home}/.m2/settings-security4.xml`. That is a copy of Maven's wiring and 
will drift from it.
   - Correction to the premise: the plugin reads no passwords from `Settings`, 
only the active proxy host, port and `nonProxyHosts`. For settings passwords 
the v4 route is `Session.getSettings()`: `maven-impl` wraps settings in a 
`DecryptingSettingsTransformer` for server and proxy passwords (seen in 
bytecode, not executed here).
   - `Settings` has no `getActiveProxy()`; the plugin takes the first `Proxy` 
with `isActive()`.
   - `ProjectManager` has no DI binding in rc-7 (`No binding to construct an 
instance for key ProjectManager`; `ArtifactManager`, `ToolchainManager`, 
`Session`, `Project`, `Log` do bind). The plugin uses 
`session.getService(ProjectManager.class)`.
   - Toolchains silently stop working if the v4 toolchain is handed over as is: 
maven-shared-utils calls `findTool(String)` reflectively on the object's class, 
which is the non-public `DefaultJavaToolchainFactory$DefaultJavaToolchain`, so 
it logs `unexpected IllegalAccessException` at WARN and runs the JDK that runs 
Maven. `ToolchainAdapter` is a public wrapper for that call. A plugin on any 
`maven-shared-utils` `JavaTool` (jmod, jlink, jdeps, jdeprscan) has the same 
trap.
   - `@Mojo` has no `threadSafe` attribute; `sign` keeps its own `threadCount` 
executor.
   - The v4 `plugin.xml` lists every parameter with `<defaultValue>` and has no 
`<configuration>` block; the test helper `PluginXmlParser` reads the new 
layout. An unset `String[]` parameter (`tsa`, `tsacert`, `tsapolicyid`) arrives 
as an empty array, as the `basic` IT shows.
   
   **User-visible changes**
   - Needs Maven 4.0.0-rc-7 or newer and Java 17; the `<prerequisites>` follows 
`mavenVersion`. The plugin no longer loads under Maven 3.
   - No goal or parameter name changes. Old-format encrypted passwords keep 
working through the legacy dispatcher.
   - Runtime dependencies: plexus-sec-dispatcher goes from 
`org.sonatype.plexus:1.4` to `org.codehaus.plexus:4.2.0`, both bundled.
   
   **Improvements:** drops `maven-plugin-api`, `maven-core`, `maven-artifact`, 
`maven-settings`, `maven-plugin-annotations`, `javax.inject` and the Plexus 
component descriptor.
   
   **Recommendation:** port once the gaps are in the open: a decrypt service in 
the API, `ProjectManager` bindable, and a public toolchain type or `findTool` 
hook in maven-shared-utils. Release it as a separate 4.x line; the 3.x line 
keeps serving Maven 3.
   
   </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