Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/site/markdown/about-checksums.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ metadata. Checksums are usually laid out in repositories next to the file in que
extension telling the checksum algorithm that produced the given checksum file content. Currently,
most Maven repositories contain SHA-1 and MD5 checksums by default (they are produced by Resolver by default).

Historically, Maven Resolver used `java.security.MessageDigest` to implement checksums. So to say, secure one-way
Historically, Maven Resolver used `java.security.MessageDigest` to implement checksums. So to speak, secure one-way
hashes provided by Java Cryptography Architecture were (mis)used to implement checksums for transport integrity
validation. There is no misunderstanding here, secure hashes MAY be used as checksums, as there is quite some
overlap between checksums and hashes in general. But this simplicity comes at a price: cryptographically safe
Expand All @@ -41,17 +41,17 @@ validation" or "error detection" (aka "bit-rot detection").

## Checksum Algorithms SPI

From a technical perspective, the above written facts infer following consequences: as checksum algorithms are exposed
to the user, so one can set them via configuration, users are not prevented to ask for SHA-256 or even SHA-512, even if
these algorithms are not part of standard Maven process. Moreover, nothing prevent users (integrating
Maven Resolver) registering with Java an alternate Java Cryptography Provider and use even broader (or exotic) set
of message digests for checksums. While this is not wrong or even mistake in any case, we do consider this as
wrong use case. The notion of transport validation and secure hashes are being constantly mixed up due historical
From a technical perspective, the above written facts imply the following consequences: because checksum algorithms are exposed
to the user, one can set them via configuration, and thus users are not prevented from asking for SHA-256 or even SHA-512, even if
these algorithms are not part of standard Maven process. Moreover, nothing prevents users (integrating
Maven Resolver) registering an alternate Java Cryptography Provider and using even broader (or exotic)
message digest algorithms for checksums. While this is not wrong, we do consider this as a
bad use case. The notion of transport validation and secure hashes are being constantly mixed up due to historical
reasons explained above.

Hence, Maven Resolver team decided to make supported set of checksums more controlled. Instead of directly exposing
Hence, the Maven Resolver team decided to make the supported set of checksum algorithms more controlled. Instead of directly exposing
`MessageDigest` algorithms, we introduced an SPI around checksums. This not only prevents wrong use cases (not
exposing all supported algorithms of `MessageDigest` to users), but also makes possible to introduce real checksum
exposing all supported algorithms of `MessageDigest` to users), but also makes it possible to introduce real checksum
algorithms. Finally, the set of supported checksum algorithms remains extensible: if some required algorithm is
not provided by Resolver, it can be easily added by creating a factory component for it.

Expand Down
14 changes: 6 additions & 8 deletions src/site/markdown/api-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,9 @@ changes using version number. We use "major.minor.patch" versioning on resolver
semantics:

* On major version change, one should NOT expect any backward compatibility.
* On minor version change, we TRY to keep backward compatibility for those "exposed" 3 modules:
API, SPI and Util. Still, there are examples when we failed to do so, usually driven by new
features.
* On minor version change, we ENSURE backward compatibility for those "exposed" 3 modules: API,
SPI and Util.
* On minor version change, we ENSURE backward compatibility for those "exposed" 3 modules: API,
SPI and Util. Still, there are examples when we failed to do so, usually driven by new
features.
Comment thread
elharo marked this conversation as resolved.
Outdated

In any of three version changes above, in areas where we do not offer guarantees, everything
can happen.
Expand All @@ -88,9 +86,9 @@ above.

## Inside of Maven

Historically, Maven 3.1 (as Maven 3.0 used resolver from different package) provided API, SPI
and Impl from its own embedded resolver, while Util, Connector, if some plugin or extension
depended on those, was resolved. This caused that a plugin may work with different versions
Historically, Maven 3.1 (as Maven 3.0 used a resolver from a different package) provided API, SPI
and Impl from its own embedded resolver, while Util and Connector, if some plugin or extension
depended on them, were resolved separately. This caused that a plugin may work with different versions
of API, SPI, Impl or Connector. Given Resolver had API "frozen" for too long time, this was essentially
not a problem, but still weird.

Expand Down
10 changes: 5 additions & 5 deletions src/site/markdown/common-misconceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ Due to smooth transitions from Maven2 into Maven3 (and soon
Maven4), and the fact that Maven2 plugins kept working with Maven3, maybe
even without change, there were some misconceptions crept in
as well. Despite the marvel of "compatibility", Maven3 resolution
differs quite much from Maven2, and the sole reason is actual improvement
differs considerably from Maven2, and the sole reason is actual improvement
in area of resolution, it became much more precise (and, due
that lost some "bad" habits present in Maven2). Here, we will try to
to that, lost some "bad" habits present in Maven2). Here, we will try to
enumerate some of the most common misconceptions.

## Misconception No1: How Resolver Works
Expand All @@ -36,7 +36,7 @@ dependencies. Resolver, to achieve this, internally (but these are
exposed via API as distinguished API calls as well) performs 3 steps:
"collect", "transform" and "resolve".

The "collect" step is first, where it builds the "dirty tree" (dirty graph)
The "collect" step is first, where it builds the "dirty tree" (or dirty graph)
of artifacts. It is important to remark, that in "collect" step, while
the graph is being built, Maven uses only POMs. Hence, if collecting an
Artifact that was never downloaded to your local repository, it will
Expand Down Expand Up @@ -81,8 +81,8 @@ a showcase how Resolver works.
## Misconception No2: "Test graph" Is Superset Of "Runtime graph"

**Wrong**. As can be seen from above, for runtime graph we leave out "test" scoped
dependencies. It was true in Maven2, where test graph really was superset of runtime,
this does not stand anymore in Maven3. And this have interesting consequences. Let me show an example:
dependencies. It was true in Maven2, where test graph really was a superset of runtime,
but this does not stand anymore in Maven3. And this have interesting consequences. Let me show an example:
Comment thread
Copilot marked this conversation as resolved.
Outdated

(Note: very same scenario, as explained below for Guice+Guava would work for Jackson Databind+Core, etc.)

Expand Down
6 changes: 3 additions & 3 deletions src/site/markdown/creating-a-repository-system-session.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ import org.eclipse.aether.supplier.RepositorySystemSupplier;
...
private static RepositorySystemSession newSession( RepositorySystem system )
{
RepositorySystemSession.SessionBuilder sessionBuilder = SessionBuilderSupplier.get();
RepositorySystemSession.SessionBuilder sessionBuilder = system.createSessionBuilder();

LocalRepository localRepo = new LocalRepository( "target/local-repo" );
sessionBuilder.setLocalRepositoryManager( system.newLocalRepositoryManager( session, localRepo ) );
sessionBuilder.setLocalRepositoryManager( system.newLocalRepositoryManager( sessionBuilder, localRepo ) );

return session.build();
return sessionBuilder.build();
Comment on lines 40 to +43
Comment on lines +38 to +43

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still won't compile: all three overloads of newLocalRepositoryManager require a RepositorySystemSession as the first argument, and SessionBuilder does not extend RepositorySystemSession.

The SessionBuilder API provides withLocalRepositories(LocalRepository...) for exactly this purpose:

Suggested change
RepositorySystemSession.SessionBuilder sessionBuilder = system.createSessionBuilder();
LocalRepository localRepo = new LocalRepository( "target/local-repo" );
sessionBuilder.setLocalRepositoryManager( system.newLocalRepositoryManager( session, localRepo ) );
sessionBuilder.setLocalRepositoryManager( system.newLocalRepositoryManager( sessionBuilder, localRepo ) );
return session.build();
return sessionBuilder.build();
RepositorySystemSession.SessionBuilder sessionBuilder = system.createSessionBuilder();
LocalRepository localRepo = new LocalRepository( "target/local-repo" );
sessionBuilder.withLocalRepositories( localRepo );
return sessionBuilder.build();

}
```
Comment on lines +38 to 45

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix correctly replaces the undefined session variable and SessionBuilderSupplier, but system.newLocalRepositoryManager(sessionBuilder, localRepo) will not compile: newLocalRepositoryManager expects a RepositorySystemSession as its first argument, and SessionBuilder does not extend RepositorySystemSession.

The SessionBuilder API provides withLocalRepositories(LocalRepository...) for this purpose, which would make the example both simpler and correct:

Suggested change
RepositorySystemSession.SessionBuilder sessionBuilder = system.createSessionBuilder();
LocalRepository localRepo = new LocalRepository( "target/local-repo" );
sessionBuilder.setLocalRepositoryManager( system.newLocalRepositoryManager( session, localRepo ) );
sessionBuilder.setLocalRepositoryManager( system.newLocalRepositoryManager( sessionBuilder, localRepo ) );
return session.build();
return sessionBuilder.build();
}
```
RepositorySystemSession.SessionBuilder sessionBuilder = system.createSessionBuilder();
LocalRepository localRepo = new LocalRepository( "target/local-repo" );
sessionBuilder.withLocalRepositories( localRepo );
return sessionBuilder.build();


Expand Down
4 changes: 2 additions & 2 deletions src/site/markdown/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ Deploying artifacts and related metadata to a (remote) repository can be achieve

The most prominent consumer of this API is probably [maven-deploy-plugin](https://maven.apache.org/plugins/maven-deploy-plugin/).

# Repository Connector
## Repository Connector

The default repository connector implementation at [`BasicRepositoryConnectorFactory`](https://github.com/apache/maven-resolver/blob/master/maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/BasicRepositoryConnector.java) uses a `RepositoryLayout` to calculate the URL and a `Transporter` to achieve the actual upload/write of artifacts/metadata.
The default repository connector implementation at [`BasicRepositoryConnector`](https://github.com/apache/maven-resolver/blob/master/maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/BasicRepositoryConnector.java) uses a `RepositoryLayout` to calculate the URL and a `Transporter` to achieve the actual upload/write of artifacts/metadata.

## Repository Layout

Expand Down
6 changes: 3 additions & 3 deletions src/site/markdown/how-resolver-works.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ The term "resolving" is a bit overloaded, but in general it involves following s

We call an artifact "resolvable" if it can be resolved from any available (local or remote) repository. To make an artifact
"resolvable" from the local repository, one needs to "install" it. To make an artifact "resolvable" from a remote repository,
one needs to "deploy" it (this is an over-simplification; publishing is new term, but it also involves deploy step).
one needs to "deploy" it (this is an over-simplification; publishing is a new term, but it also involves deploy step).
Furthermore, there are extension points like `WorkspaceReader` that can make artifacts resolvable
without installing or deploying them, but that is an integration detail (like Maven does by exposing reactor projects).

Expand All @@ -61,7 +61,7 @@ The BF collector is now the default, as it offers better performance.

One very important thing, that is constantly misunderstood, is what information is used during graph collection.
Only certain parts of the effective model are used, not the whole POM.
If I am allowed to overly simplify, only the following aspects of the effective model are used during graph collection:
If I may oversimplify, only the following aspects of the effective model are used during graph collection:
* `project/dependencies` as direct dependencies on given node
* `project/dependencyManagement/dependencies` for **subsequent** dependency management on given node
* `project/repositories` for **subsequent** repositories to be used on given node
Expand Down Expand Up @@ -114,7 +114,7 @@ In general, the steps "dependency graph collection" and "conflict resolution" ar
The "flattening" and "artifact resolving" are also usually done together, and we use for those the term "artifact resolution".
To make the story more confusing, when all the steps are performed together is also called "dependency resolution".
The Resolver API reflects this terminology and offers methods doing collection, resolution or both.
*

* The method `CollectResult collectDependencies(RepositorySystemSession session, CollectRequest request)` performs only the collection step,
as its name suggests. Hence, only the steps "collection" and "conflict resolution" are performed.
* Method `List<ArtifactResult> resolveArtifacts(RepositorySystemSession session, Collection<? extends ArtifactRequest> requests)`
Expand Down
8 changes: 4 additions & 4 deletions src/site/markdown/local-repository.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ can happen based even on origin repository (if split by remote repository
was enabled beforehand).

Example configuration with split by remote repository:
```java
```sh
$ mvn ... -Daether.enhancedLocalRepository.split \
-Daether.enhancedLocalRepository.splitRemoteRepository
```
Expand All @@ -124,9 +124,9 @@ coexist in local repository. They will land in different places, due different
prefixes.

Example configuration for branches:
```java
```sh
$ mvn ... -Daether.enhancedLocalRepository.split \
-Daether.enhancedLocalRepository.localPrefix=maven-resolver/mresolver-253
-Daether.enhancedLocalRepository.localPrefix=maven-resolver/mresolver-253 \
-Daether.enhancedLocalRepository.splitRemoteRepository
```

Expand Down Expand Up @@ -197,7 +197,7 @@ Each artifact/metadata which cannot be resolved leads to an error either classif
1. *not found* error or
2. (any) *other* error (for authentication issues, timeouts etc.)

The caching behavior for both error types can be be configured programmatically via `org.eclipse.aether.DefaultRepositorySystemSession.setResolutionErrorPolicy(...)`.
The caching behavior for both error types can be configured programmatically via `org.eclipse.aether.DefaultRepositorySystemSession.setResolutionErrorPolicy(...)`.

In case caching is enabled for any of the two classifications a Java Properties file is created/updated (with the same filename as the cached artifact in the success case would get but with the additional suffix `.lastUpdated`) in the local repository. Within that file the key `<canonical-remote-url>.error` is updated/added. Its value either contains the error message (for type 2 resolver errors) or is empty (for type 1 resolver errors).

Expand Down
6 changes: 3 additions & 3 deletions src/site/markdown/remote-repository-filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ and artifacts are resolved using a loop and a "first found wins" strategy. This
### What It Is

You can instruct Maven which repository can contain which artifacts. Instead of "ordered loop" searching
for artifacts in remote repositories, Maven can query a repository that has the artifact first,.
for artifacts in remote repositories, Maven can query a repository that has the artifact first.

With RRF, the Maven build does not slow down when new remote repositories are added, and does not leak
build information unnecessarily.
Expand Down Expand Up @@ -193,7 +193,7 @@ applied. Ideally, user should keep files sorted or handle them in a way one can

To make RRF filters operate, as they are by default enabled, you have to make sure that:
* prefix file can be discovered (if not for any reason, you may provide alternate input for it)
* groupId is procided.
* groupId is provided.

As said above, enabled filters does not make them active (participate in filtering): if a given remote repository does not have
any input available, the filter pulls out from "voting" (does not participate in filtering, will abstain
Expand All @@ -217,6 +217,6 @@ This leads to the following "constraints":

Users of certain Maven Repository Managers (MRM) reported issues with filtering, breaking their builds. Usually the issue involves grouped/virtual repositories where MRM leaks random resources from member repositories, like the `prefixes.txt` is. Naturally, as MRM leaks one member prefixes file, and Maven is "tricked" into belief it got proper prefixes file from remote repository, builds will fail with message like **Prefix `$PREFIX` NOT allowed from `$SERVER_ID`** (where `$PREFIX` is some artifact prefix, and `$SERVER_ID` is some remote repository ID).

In this case, user should disable prefix discovery by using `-Daether.remoteRepositoryFilter.prefixes.resolvePrefixFiles=false` user property to prevent Maven attempting to resolve prefixes file from such broken MRMs.
In this case, user should disable prefix discovery by using `-Daether.remoteRepositoryFilter.prefixes.resolvePrefixFiles=false` user property to prevent Maven from attempting to resolve the prefixes file from such broken MRMs.

Since 2.0.21, Resolver protects itself against this failure mode: when an auto-discovered prefixes file denies a path, the very first denial per remote repository is verified against the remote repository itself using a lightweight existence check. If the repository actually serves the denied path, the auto-discovered prefixes file is provably wrong; a warning naming the repository is emitted (report it to the repository administrator) and the file is ignored for the rest of the session, so the build proceeds as if no prefixes file was published. If the denied path is indeed absent remotely, the file remains trusted and no further checks are performed, keeping the extra cost bounded at one existence check per remote repository per session. User-provided prefix files are considered deliberate and are never second-guessed. The verification can be disabled with `-Daether.remoteRepositoryFilter.prefixes.verifyDenied=false` (supports repository ID suffix as well).
2 changes: 1 addition & 1 deletion src/site/markdown/repository-key-function.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Furthermore, repository key function (possibly different one) is used in two com
* Trusted Checksums Source
* Remote Repository Filter

In these cases, the repository key function only role is to provide "file system friendly" path segments based on
In these cases, the repository key function's only role is to provide "file system friendly" path segments based on
`RemoteRepository` instances.

**Important implication:** When Resolver/Maven is reconfigured to use alternative repository key function, it is
Expand Down
2 changes: 1 addition & 1 deletion src/site/markdown/third-party-integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ from the beginning. Back when SL was implemented, the DI container in use with R
Maven was the Plexus DI container, that had its own limitations: no constructor injection
among others. Hence, the two was somewhat aligned with each other. Today, with Sisu DI,
this is not true anymore: we want to use constructor injection for components, but
SL is always getting into our way forcing us to always add default constructor to components.
SL is always getting in our way forcing us to always add default constructor to components.
Hence, decision was made, and SL was deprecated while ago, and is about to be
dropped in Resolver 2.0.0 release.

Expand Down
2 changes: 1 addition & 1 deletion src/site/markdown/transporter-known-issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This page lists known issues related to various transporters.

## The `jdk` (Java HttpClient) Transporter

Given this transporter uses the Java HttpClient (available since Java 11), it is the user's best interest
Given this transporter uses the Java HttpClient (available since Java 11), it is in the user's best interest
to use latest patch version of Java, as HttpClient is getting bugfixes regularly.

### Known issues:
Expand Down
4 changes: 2 additions & 2 deletions src/site/markdown/upgrading-resolver.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ Required changes in **consumer project code managing Resolver 2.x**:
## 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 it's major
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 (sans two "core" ones: type and language), as it is really matter of the consumer project assign semantics to them.
* 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).
Expand Down
4 changes: 2 additions & 2 deletions src/site/markdown/what-is-resolver.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@ makes Resolver "minimally complete" (contains required component implementations
and introduces required models for Maven repositories). But this is still
just "basic resolver functionality". Next functionality
level is add "Maven environment awareness" (like honoring settings.xml and alike). This
can be achieved by using libraries like [MIMA](https://github.com/maveniverse/mima)
is. And finally, Maven (that incorporates Resolver) offers full experience (while
can be achieved by using libraries like [MIMA](https://github.com/maveniverse/mima).
And finally, Maven (that incorporates Resolver) offers full experience (while
embedding Maven is really not trivial).
2 changes: 1 addition & 1 deletion src/site/xdoc/index.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
</p>

<p>
<img src="images/maven-resolver-deps.png" width="792" height="441" border="0" usemap="#Maven_Resolver_dependencies" />
<img src="images/maven-resolver-deps.png" width="792" height="441" border="0" usemap="#Maven_Resolver_dependencies" alt="" />
Comment thread
Copilot marked this conversation as resolved.
Outdated
<map name="Maven_Resolver_dependencies">
<area shape="rect" coords="285,405,348,441" href="./maven-resolver-api/" />
<area shape="rect" coords="286,335,349,370" href="./maven-resolver-spi/" />
Expand Down
Loading