-
Notifications
You must be signed in to change notification settings - Fork 127
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MRESOLVER-289][MRESOLVER-526] Reuse relevant bits from Eclipse Aethe…
…r wiki contents (#496) With applied updates for Resolver 2.0. Reworked side menu: * Overview (as before) * Guides (added) * Reference (added) * See also (as before) Content from EOLd Eclipse wiki https://wiki.eclipse.org/Aether The dump is attached to MRESOLVER-526 but is filtered (outdated pages omitted) as explained on issue. --- https://issues.apache.org/jira/browse/MRESOLVER-526 https://issues.apache.org/jira/browse/MRESOLVER-289
- Loading branch information
Showing
8 changed files
with
481 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Creating a RepositorySystemSession | ||
<!-- | ||
Licensed to the Apache Software Foundation (ASF) under one | ||
or more contributor license agreements. See the NOTICE file | ||
distributed with this work for additional information | ||
regarding copyright ownership. The ASF licenses this file | ||
to you under the Apache License, Version 2.0 (the | ||
"License"); you may not use this file except in compliance | ||
with the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, | ||
software distributed under the License is distributed on an | ||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations | ||
under the License. | ||
--> | ||
|
||
Resolver (former Aether) and its components are designed to be stateless and as such all | ||
configuration/state has to be passed into the methods. When one makes | ||
multiple requests to resolve dependencies, a fair amount of settings | ||
usually remains the same across these method calls, like the proxy | ||
settings or the path to the local repository. Those settings that tend | ||
to be the same for an entire usage session of the repository system are | ||
represented by an instance of | ||
`org.eclipse.aether.RepositorySystemSession`. Using classes from | ||
`maven-resolver-supplier`, creating such a session that mimics Maven's | ||
setup can be done like this: | ||
|
||
```java | ||
import org.eclipse.aether.supplier.RepositorySystemSupplier; | ||
|
||
... | ||
private static RepositorySystemSession newSession( RepositorySystem system ) | ||
{ | ||
RepositorySystemSession.SessionBuilder sessionBuilder = SessionBuilderSupplier.get(); | ||
|
||
LocalRepository localRepo = new LocalRepository( "target/local-repo" ); | ||
sessionBuilder.setLocalRepositoryManager( system.newLocalRepositoryManager( session, localRepo ) ); | ||
|
||
return session.build(); | ||
} | ||
``` | ||
|
||
As you see, the only setting that must be specified is the local | ||
repository, other settings are initialized with default values. Please | ||
have a look at the API docs for `RepositorySystemSession.SessionBuilder` to | ||
learn about all the other things you can configure for a session. | ||
|
||
In case of Maven plugin, or when code runs embedded in Maven, the session | ||
is already created for you, but you can still "derive" using copy constructor | ||
of `DefaultRepositorySystemSession` if some session alteration is needed. | ||
|
||
If you seek a closer cooperation with [Apache | ||
Maven](http://maven.apache.org/) and want to read configuration from the | ||
user's `settings.xml`, you should have a look at the library | ||
[MIMA](https://github.com/maveniverse/mima) which provides the necessary | ||
bits. Please direct any questions regarding usage of that library to the | ||
Maven mailing list. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Dependency Graph | ||
<!-- | ||
Licensed to the Apache Software Foundation (ASF) under one | ||
or more contributor license agreements. See the NOTICE file | ||
distributed with this work for additional information | ||
regarding copyright ownership. The ASF licenses this file | ||
to you under the Apache License, Version 2.0 (the | ||
"License"); you may not use this file except in compliance | ||
with the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, | ||
software distributed under the License is distributed on an | ||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations | ||
under the License. | ||
--> | ||
|
||
When resolving transitive dependencies, Resolver (former Aether) constructs a *dependency | ||
graph* consisting of `DependencyNode` instances where each node | ||
represents a dependency and its direct dependencies are represented as | ||
child nodes. During early stages of the resolution process, there are | ||
usually duplicate dependencies or even cycles in the graph as sketched | ||
below: | ||
|
||
``` | ||
root | ||
/ \ | ||
/ \ | ||
a:1 b:1 <--+ | ||
\ / \ | | ||
\ / \ | | ||
c:1 a:2 | | ||
| | | ||
+---------+ | ||
``` | ||
|
||
Once this dependency graph has undergone conflict resolution, i.e. | ||
duplicate dependencies have been removed, one actually has a *dependency | ||
tree*. Taking the previous example, the tree might look like this: | ||
|
||
``` | ||
root | ||
/ \ | ||
/ \ | ||
a:1 b:1 | ||
| | ||
| | ||
c:1 | ||
``` | ||
|
||
The dependency tree is a handy data structure to get the complete set of | ||
artifacts one would need to form a classpath etc. as a simple recursive | ||
traversal is sufficient to gather the relevant dependencies. | ||
|
||
## Troubleshooting a Dependency Graph | ||
|
||
The dependency tree provides a compact and basic means to end users to | ||
understand why/how a given artifact ended up among the dependencies. But | ||
as the examples above illustrate, the dependency tree misses some | ||
information compared to the dependency graph. For instance, the tree | ||
does not indicate that `b:1` also depends on `c:1`. To help | ||
troubleshooting complex dependency graphs, some configuration properties | ||
exist to keep useful data in the dependency graph returned by | ||
`RepositorySystem.collectDependencies()`. | ||
|
||
For instance, the configuration property | ||
`ConflictResolver.CONFIG_PROP_VERBOSE` can be enabled to produce a graph | ||
similar to m2e's dependency hierarchy view where conflicting nodes are | ||
retained. This gives end users a better understanding of all the paths | ||
that pull in a given dependency. | ||
|
||
The configuration property `DependencyManagerUtils.CONFIG_PROP_VERBOSE` | ||
can be enabled to record the attributes of a dependency before they were | ||
updated due to dependency management. This helps end users to understand | ||
why one version of a dependency and not the other is found in the graph | ||
or why a dependency ended up in a given scope. | ||
|
||
Please see the API docs for said configuration properties for details | ||
regarding their effects and ways to access the additional data. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# Resolving Dependencies | ||
<!-- | ||
Licensed to the Apache Software Foundation (ASF) under one | ||
or more contributor license agreements. See the NOTICE file | ||
distributed with this work for additional information | ||
regarding copyright ownership. The ASF licenses this file | ||
to you under the Apache License, Version 2.0 (the | ||
"License"); you may not use this file except in compliance | ||
with the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, | ||
software distributed under the License is distributed on an | ||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations | ||
under the License. | ||
--> | ||
|
||
Extending the code snippets from [Creating a RepositorySystemSession](creating-a-repository-system-session.html), the snippet below demonstrates | ||
how to actually resolve the transitive dependencies of say | ||
`org.apache.maven:maven-core:3.9.6` and to dump the result as a class | ||
path to the console: | ||
|
||
```java | ||
public static void main( String[] args ) | ||
throws Exception | ||
{ | ||
RepositorySystem repoSystem = newRepositorySystem(); | ||
|
||
RepositorySystemSession session = newSession( repoSystem ); | ||
|
||
Dependency dependency = | ||
new Dependency( new DefaultArtifact( "org.apache.maven:maven-core:3.9.6" ), "compile" ); | ||
RemoteRepository central = new RemoteRepository.Builder( "central", "default", "https://repo.maven.apache.org/maven2/" ).build(); | ||
|
||
CollectRequest collectRequest = new CollectRequest(); | ||
collectRequest.setRoot( dependency ); | ||
collectRequest.addRepository( central ); | ||
DependencyNode node = repoSystem.collectDependencies( session, collectRequest ).getRoot(); | ||
|
||
DependencyRequest dependencyRequest = new DependencyRequest(); | ||
dependencyRequest.setRoot( node ); | ||
|
||
repoSystem.resolveDependencies( session, dependencyRequest ); | ||
|
||
PreorderNodeListGenerator nlg = new PreorderNodeListGenerator(); | ||
node.accept( nlg ); | ||
System.out.println( nlg.getClassPath() ); | ||
} | ||
``` | ||
|
||
So once you have initialized the repository system and created a | ||
session, the general pattern is to create some request object, call its | ||
setters to configure the request, do the operation and evaluate the | ||
result object. | ||
|
||
Since "all theory is grey", we maintain some runnable | ||
[examples and demos](https://github.com/apache/maven-resolver/tree/master/maven-resolver-demos) among | ||
our sources. These examples provide a more extensive demonstration of | ||
Resolver and its use, so what are you waiting for? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# Transitive Dependency Resolution | ||
<!-- | ||
Licensed to the Apache Software Foundation (ASF) under one | ||
or more contributor license agreements. See the NOTICE file | ||
distributed with this work for additional information | ||
regarding copyright ownership. The ASF licenses this file | ||
to you under the Apache License, Version 2.0 (the | ||
"License"); you may not use this file except in compliance | ||
with the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, | ||
software distributed under the License is distributed on an | ||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations | ||
under the License. | ||
--> | ||
|
||
An important task of Resolver (former Aether) is to resolve transitive dependencies. This | ||
task can be split into two sub-tasks: | ||
|
||
1. Determine the coordinates of the artifacts that make up the | ||
transitive dependencies. | ||
2. Resolve the files for the artifacts that have been identified in | ||
step 1. | ||
|
||
Artifacts and their dependencies among each other form a *[dependency graph](dependency-graph.html)*. So in other | ||
words, step 1 means to calculate this dependency graph and step 2 is a | ||
simple graph traversal that fetches the file for each artifact in the | ||
dependency graph. In Resolver, this dependency graph can be easily | ||
inspected and extension points are provided to allow for more control | ||
over the construction of the dependency graph. To understand those | ||
extension points, we will have a closer look at the way the dependency | ||
graph is constructed. | ||
|
||
Starting from a given root dependency like | ||
`org.eclipse.aether:aether-impl:0.9.0`, the repository system first | ||
reads the corresponding *artifact descriptor* (i.e. the POM when dealing | ||
with Maven repositories). The artifact descriptor tells about direct | ||
dependencies, dependency management and additional remote repositories | ||
to consider during the resolution. For each direct dependency, a | ||
*dependency selector* is given a chance to exclude the dependency from | ||
the graph. If the dependency is included, a *dependency manager* applies | ||
dependency management (if any). Next, the declared dependency version is | ||
expanded to a list of matching versions from the repositories. For a | ||
simple version like "1.0", the resulting list contains only that | ||
version. For a version range like "\[1.0,2.0)", the version list | ||
generally contains multiple versions and is subject to filtering by a | ||
*version filter*. For each matching version of the dependency, a child | ||
node is added to the dependency graph. Recursion of the process for each | ||
child dependency is controlled by a *dependency traverser*. | ||
|
||
The above process creates a dependency graph that often contains | ||
duplicate or conflicting dependencies or even cycles and as such is | ||
called a *dirty graph*. A chain of *dependency graph transformers* is | ||
then used to trim this graph down and to form a *resolved graph*. | ||
|
||
So more technically, the dependency graph that the repository system | ||
returns to its caller is affected by instances of | ||
`org.eclipse.aether.collection.DependencySelector`, | ||
`org.eclipse.aether.collection.DependencyManager`, | ||
`org.eclipse.aether.collection.VersionFilter`, | ||
`org.eclipse.aether.collection.DependencyTraverser` and | ||
`org.eclipse.aether.collection.DependencyGraphTransformer`. Users of the | ||
repository system can directly control those extension points when | ||
creating the repository system session by providing implementations that | ||
fit their needs. | ||
|
||
For example, a dependency selector can process exclusions on child | ||
dependencies, exclude optional dependencies or dependencies with certain | ||
unwanted scopes. A dependency traverser can be used to decide whether | ||
the dependencies of a (fat) WAR should be included in the dependency | ||
graph or not. The version filter can exclude specific versions of an | ||
artifact which are unacceptable in the current context, e.g. ban | ||
snapshots. Dependency graph transformers can identify and mark | ||
conflicting nodes in the dirty tree and resolve conflicting versions or | ||
scopes by pruning unwanted parts from the graph. | ||
|
||
Several classes from `maven-resolver-provider` helps to construct a | ||
session that mimics the resolution rules used by Maven. In | ||
case you want to customize the graph construction, feel free to have a | ||
look at the source of that class to learn about the implementation | ||
classes being used there to achieve Maven style behavior, you might want | ||
to reuse some of those for your own repository system session as well. | ||
Maven plugins can easily get access to the current repository system | ||
session via the usual parameter injection, see for the actual code bits. |
Oops, something went wrong.