gnodet-bot commented on code in PR #2280: URL: https://github.com/apache/maven-resolver/pull/2280#discussion_r4503968011
########## src/site/markdown/upgrading-resolver.md: ########## @@ -48,23 +117,133 @@ Required changes in **consumer project code managing Resolver 2.x**: * to shallow-copy session instances (for alteration purposes) using existing `DefaultRepositorySystemSession` copy constructor is acceptable (this is what Mojos do). * to shallow-copy session instances but have new lifecycle as well, use `SessionBuilder#withRepositorySystemSession` on newly created builder instances. +## Step 3: Move from File to Path + +Resolver 2.0.0 switched its API, SPI and Util modules from `java.io.File` to +`java.nio.file.Path`. Every `File` method is still there and deprecated, delegating +to the `Path` one, so existing binaries keep working. Replace them when you move +to 2.x; the table lists the renames. + +| Module | Deprecated | Replacement | +|---|---|---| +| API | `Artifact#getFile()`, `Artifact#setFile(File)` | `getPath()`, `setPath(Path)` | +| API | `Metadata#getFile()`, `Metadata#setFile(File)`, `MergeableMetadata#merge(File, File)` | `getPath()`, `setPath(Path)`, `merge(Path, Path)` | +| API | `DefaultMetadata` constructors taking `File` | The same constructors taking `Path` | +| API | `LocalRepository(String)`, `LocalRepository(File)`, `LocalRepository(File, String)`, `LocalRepository#getBasedir()` | `LocalRepository(Path)`, `LocalRepository(Path, String)`, `getBasePath()` | +| API | `LocalArtifactResult` and `LocalMetadataResult` `getFile()`, `setFile(File)` | `getPath()`, `setPath(Path)` | +| API | `LocalRepositoryManager#getPathForLocalArtifact` and the three sibling `getPathFor*` methods returning `String` | `getAbsolutePathForLocalArtifact` and siblings returning `Path` | +| API | `RepositoryEvent#getFile()`, `RepositoryEvent.Builder#setFile(File)` | `getPath()`, `setPath(Path)` | +| API | `TransferResource#getFile()`, `TransferResource#getTransferStartTime()`, the constructor taking `File` | `getPath()`, `getStartTime()`, the constructor taking `Path` | +| SPI | `ArtifactDownload`, `ArtifactUpload`, `MetadataDownload`, `MetadataUpload` constructors taking `File`, and `setFile(File)` on them and on `ArtifactTransfer`, `MetadataTransfer` | The `Path` constructors, `setPath(Path)`, `getPath()` | +| SPI | `GetTask#getDataFile()`, `GetTask#setDataFile(...)`, `PutTask#getDataFile()`, `PutTask#setDataFile(File)` | `getDataPath()`, `setDataPath(...)` | +| SPI | `FileProcessor` | `PathProcessor` for file operations, `ChecksumProcessor` for checksum files | +| Util | `NodeListGenerator#getFiles()` | `getPaths()` | + +A plugin that must still run on Maven 3.9 cannot call `getPath()`, because Maven +3.9 ships Resolver 1.9.x without it. Keep `getFile()` there and suppress the +warning; the plugin guide explains the options. + +## Step 4: Replace the deprecated Util helpers + +| Deprecated in 2.x | Replacement | +|---|---| +| `PreorderNodeListGenerator`, `PostorderNodeListGenerator` | `PreorderDependencyNodeConsumerVisitor` and `PostorderDependencyNodeConsumerVisitor` feeding a `NodeListGenerator`; `LevelOrderDependencyNodeConsumerVisitor` matches the order Resolver 2.x uses for class paths. | +| `NearestVersionSelector` | `ConfigurableVersionSelector`, which also offers the "highest" strategy. | +| `PredicateVersionFilter` | `ArtifactPredicateVersionFilter` | +| `ScopeDependencySelector`, `OptionalDependencySelector` in `org.eclipse.aether.util.graph.selector` | The selectors a supplier session already carries, or `ScopeManager#getDependencySelector(session, resolutionScope)`. Scope semantics belong to the consumer project in 2.x. | +| `ContextualSnapshotVersionFilter#CONFIG_PROP_ENABLE` (`aether.snapshotFilter`) | Add a `SnapshotVersionFilter` to the session to ban snapshots. | +| `ChecksumUtils`, `FileUtils`, `ExecutorUtils` | `StringDigestUtil`, the `org.eclipse.aether.spi.io` processors, and the JDK. Resolver no longer uses these classes. | +| `RepositoryPolicy#getUpdatePolicy()` | `getArtifactUpdatePolicy()` and `getMetadataUpdatePolicy()`. Resolver 2.x keeps the two policies apart; the old method returns the artifact one. | +| `ArtifactResult#addException(Exception)` | `addException(ArtifactRepository, Exception)`, so the failure is attributed to a repository. | +| `UnsolvableVersionConflictException(Collection)` | `UnsolvableVersionConflictException(String, Collection)` with a message. | +| `BasicRepositoryConnectorConfigurationKeys#CONFIG_PROP_THREADS` (`aether.connector.basic.threads`) | `CONFIG_PROP_UPSTREAM_THREADS` and `CONFIG_PROP_DOWNSTREAM_THREADS` | + ## Consumer Project Changes (if more needed) -Maven Resolver 2.x now fully delegates multiple aspects to the consumer project, itself remaining "oblivious" about -them. This was done to lessen (or better, fully remove) any overlap between the logic of the Resolver, and its major -consumer project: Maven. The following aspects are fully delegated to consumer projects: -* Most of the `ArtifactProperties` is deprecated (except two "core" ones: type and language), as it is really a matter of the consumer project to assign semantics to them. -* The `ArtifactType` default implementation is deprecated, should be provided by consumer project instead, Resolver 2.x should not provide implementations for it. -* Class path generation (in NodeListGenerator class variations in `org.eclipse.aether.util.graph.visitor` package) and class path filtering (in `DependencyFilterUtils`) is deprecated. It is the consumer app, based on own artifact properties, that can deduce how to build class path (or module path, or anything alike). -* Dependency Scopes are fully removed. For Resolver, they were always "just labels". Resolver is now fully unaware of scopes (and for "system" artifacts has a dedicated handler exposed on session). - -For users of Maven Resolver Provider module, these changes will have clean migration path, as all the replacements for -items from the list above are present in `org.apache.maven:maven-resolver-provider` module. Still, for binary -compatibility, all affected classes are in fact left in place, but deprecated. Consumer projects should update -accordingly, and if they do use any deprecated classes from the resolver (affected modules are maven-resolver-api -and maven-resolver-util), they should switch to their counterparts, that are now present in maven-resolver-provider -module. - -Note: Resolver 2.x still fully supports "legacy" (Maven3-like) functionality, and if existing consumer -code base adapts only the session related changes, consumer project can enjoy new features (like HTTP/2 transport), -while keeping full compatibility, identical to Resolver 1.x release. +Resolver 2.x delegates the Maven specific parts of dependency handling to the +consumer project. Resolver itself treats dependency scopes as labels; the meaning +of `compile`, `test`, or any other scope comes from the `ScopeManager` the +session carries, and the two supplier modules configure it for Maven 3 and Maven 4 +semantics. The same applies to the `system` scope, which has its own +`SystemDependencyScope` handler on the session. + +The Maven 3 era helpers stay available and are not deprecated: `JavaScopes`, the +`ArtifactProperties` constants, `DefaultArtifactType`, and `DependencyFilterUtils` +with its class path filters. They remain the right choice for code that must +behave like Maven 3, and the `mvn3` supplier builds on them. Code that targets +Maven 4 should take scopes, types and class path logic from Maven's own +`maven-resolver-provider` and API instead, so that it agrees with the build it runs in. + +## Step 5: Update module coordinates + +| Resolver 1.9.x | Resolver 2.x | +|---|---| +| `maven-resolver-transport-http` (Apache HttpClient 4, package `org.eclipse.aether.transport.http`) | `maven-resolver-transport-apache` (Apache HttpClient 4, package `org.eclipse.aether.transport.apache`, factory `ApacheTransporterFactory`). The connector configuration keys moved, see step 6. | +| `maven-resolver-supplier` | `maven-resolver-supplier-mvn3` or `maven-resolver-supplier-mvn4`, see step 2. | +| `maven-resolver-transport-wagon`, `maven-resolver-transport-file`, `maven-resolver-transport-classpath` | Unchanged coordinates; the configuration keys moved to the `aether.transport.*` namespace. | +| `maven-resolver-named-locks-hazelcast` | Deprecated, support will be dropped. Use the default file locks, `maven-resolver-named-locks-ipc` (Java 17) for a lock daemon shared between JVMs, or `maven-resolver-named-locks-redisson` (Java 11). | + +New in 2.x, all optional: + +* `maven-resolver-transport-jdk`: HTTP/1.1 and HTTP/2 through `java.net.http`, a multi-release jar that is defunct on Java 8 and active on Java 11 and later. HTTP/3 since 2.0.21 on JDKs that support it. +* `maven-resolver-transport-jetty`: HTTP/2 and HTTP/3 through Jetty, Java 17. +* `maven-resolver-transport-url`: a small `java.net.URL` transport, Java 8. +* `maven-resolver-transport-minio`: native S3 transport. +* `maven-resolver-generator-gnupg` and `maven-resolver-generator-sigstore`: sign artifacts at deploy time, Java 17. + +When more than one HTTP transport is on the class path the highest priority wins: +Jetty (15), then JDK (10), then Apache (5). The Wagon and URL transports have a +negative priority and only serve when nothing else can. Set the `aether.priority.*` +properties to change the order. + +## Step 6: Rename configuration keys + +The 2.x keys live under `aether.transport.*` for transports and `aether.lrm.*`, +`aether.named.*`, `aether.system.*` for the rest. The full, generated list with +defaults and the version each key appeared in is on the +[Configuration Options](configuration.html) page. The renames below are the ones a +1.9.x `settings.xml`, `.mvn/maven.config` or session setup is likely to contain. + +Resolver 2.x still reads the old key for the rows marked "yes" in the last column. +Every other old key is ignored silently, so grep your configuration for +`aether.connector.` and `aether.enhancedLocalRepository.` before upgrading. + +| Resolver 1.9.x key | Resolver 2.x key | Old key still read | +|---|---|---| +| `aether.connector.connectTimeout` | `aether.transport.http.connectTimeout` | no | +| `aether.connector.requestTimeout` | `aether.transport.http.requestTimeout` | no | +| `aether.connector.userAgent` | `aether.transport.http.userAgent` | yes | +| `aether.connector.http.headers` (and `.headers.<repoId>`) | `aether.transport.http.headers` | no | +| `aether.connector.http.preemptiveAuth`, `.preemptivePutAuth` | `aether.transport.http.preemptiveAuth`, `.preemptivePutAuth` | no | +| `aether.connector.http.reuseConnections`, `.connectionMaxTtl`, `.maxConnectionsPerRoute` | `aether.transport.http.reuseConnections`, `.connectionMaxTtl`, `.maxConnectionsPerRoute` | no | +| `aether.connector.http.expectContinue`, `.credentialEncoding`, `.supportWebDav` | `aether.transport.http.expectContinue`, `.credentialEncoding`, `.supportWebDav` | no | +| `aether.connector.http.retryHandler.count`, `.interval`, `.intervalMax`, `.serviceUnavailable` | `aether.transport.http.retryHandler.count`, `.interval`, `.intervalMax`, `.serviceUnavailable` | no | +| `aether.connector.http.retryHandler.name`, `.requestSentEnabled` | `aether.transport.apache.retryHandler.name`, `.requestSentEnabled` | no | +| `aether.connector.http.followRedirects`, `.maxRedirects`, `.useSystemProperties` | `aether.transport.apache.followRedirects`, `.maxRedirects`, `.useSystemProperties` | no | +| `aether.connector.bind.address` | `aether.transport.http.localAddress` | no | +| `aether.connector.http.cacheState` | Removed. | no | +| `aether.connector.https.securityMode` | `aether.transport.https.securityMode` | no | +| `aether.connector.https.cipherSuites`, `.protocols` | `aether.transport.apache.https.cipherSuites`, `.protocols` | no | +| `aether.connector.wagon.config` | `aether.transport.wagon.config` | no | +| `aether.connector.perms.fileMode`, `.dirMode`, `.group` | `aether.transport.wagon.perms.fileMode`, `.dirMode`, `.group` | no | +| `aether.connector.classpath.loader` | `aether.transport.classpath.loader` | no | +| `aether.connector.persistedChecksums` | `aether.connector.basic.persistedChecksums` | no | +| `aether.connector.smartChecksums` | `aether.connector.basic.includedChecksums` | yes | +| `aether.connector.basic.threads` | `aether.connector.basic.upstreamThreads` and `.downstreamThreads` | yes, deprecated | +| `aether.checksums.algorithms` | `aether.checksums.checksumAlgorithms` | yes | +| `aether.enhancedLocalRepository.*` (`split`, `splitLocal`, `splitRemote`, `localPrefix`, `remotePrefix`, `releasesPrefix`, `snapshotsPrefix`, `splitRemoteRepository`, `splitRemoteRepositoryLast`, `trackingFilename`) | `aether.lrm.enhanced.*` with the same suffixes | yes | Review Comment: ⚠️ **Incorrect backward-compatibility claim for `trackingFilename`** This row marks `trackingFilename` as backward-compatible (`yes`) alongside the other 9 suffixes, but that is not the case. The 9 other suffixes (`split`, `splitLocal`, `splitRemote`, `localPrefix`, `remotePrefix`, `releasesPrefix`, `snapshotsPrefix`, `splitRemoteRepository`, `splitRemoteRepositoryLast`) all have an `R1_CONF_PROP_*` constant in `LocalPathPrefixComposerFactorySupport` that provides the fallback to the old `aether.enhancedLocalRepository.*` key. `trackingFilename` has no such constant — `EnhancedLocalRepositoryManagerFactory` reads it via `ConfigUtils.getString(session, "", CONFIG_PROP_TRACKING_FILENAME)` with a single key (`aether.lrm.enhanced.trackingFilename`), no R1_CONF fallback. Either: - Add an `R1_CONF_PROP_TRACKING_FILENAME` fallback in the factory (to actually provide backward compat), or - Split `trackingFilename` out of this row and mark it `no`. -- 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]
