From b1f201547492bbeaf191ef50f89b376e46dfe528 Mon Sep 17 00:00:00 2001
From: Tamas Cservenak <tamas@cservenak.net>
Date: Tue, 14 Nov 2023 15:10:41 +0100
Subject: [PATCH 1/5] [MRESOLVER-432] Introduce Session Supplier similar to
 System Supplier

---

https://issues.apache.org/jira/browse/MRESOLVER-432
---
 .../supplier/SessionBuilderSupplier.java      | 126 ++++++++++++++++++
 .../RepositorySystemSupplierTest.java         |  45 +++----
 2 files changed, 146 insertions(+), 25 deletions(-)
 create mode 100644 maven-resolver-supplier/src/main/java/org/eclipse/aether/supplier/SessionBuilderSupplier.java

diff --git a/maven-resolver-supplier/src/main/java/org/eclipse/aether/supplier/SessionBuilderSupplier.java b/maven-resolver-supplier/src/main/java/org/eclipse/aether/supplier/SessionBuilderSupplier.java
new file mode 100644
index 000000000..e3163ef7c
--- /dev/null
+++ b/maven-resolver-supplier/src/main/java/org/eclipse/aether/supplier/SessionBuilderSupplier.java
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+package org.eclipse.aether.supplier;
+
+import java.util.function.Supplier;
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
+import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
+import org.eclipse.aether.artifact.ArtifactTypeRegistry;
+import org.eclipse.aether.artifact.DefaultArtifactType;
+import org.eclipse.aether.collection.DependencyGraphTransformer;
+import org.eclipse.aether.collection.DependencyManager;
+import org.eclipse.aether.collection.DependencySelector;
+import org.eclipse.aether.collection.DependencyTraverser;
+import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
+import org.eclipse.aether.util.artifact.DefaultArtifactTypeRegistry;
+import org.eclipse.aether.util.graph.manager.ClassicDependencyManager;
+import org.eclipse.aether.util.graph.selector.AndDependencySelector;
+import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector;
+import org.eclipse.aether.util.graph.selector.OptionalDependencySelector;
+import org.eclipse.aether.util.graph.selector.ScopeDependencySelector;
+import org.eclipse.aether.util.graph.transformer.ChainedDependencyGraphTransformer;
+import org.eclipse.aether.util.graph.transformer.ConflictResolver;
+import org.eclipse.aether.util.graph.transformer.JavaDependencyContextRefiner;
+import org.eclipse.aether.util.graph.transformer.JavaScopeDeriver;
+import org.eclipse.aether.util.graph.transformer.JavaScopeSelector;
+import org.eclipse.aether.util.graph.transformer.NearestVersionSelector;
+import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector;
+import org.eclipse.aether.util.graph.traverser.FatArtifactTraverser;
+import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A simple {@link Supplier} of {@link SessionBuilder} instances, that on each call supplies newly
+ * constructed instance. To create session out of builder, use {@link SessionBuilder#build()}. For proper closing
+ * of sessions, use {@link CloseableSession#close()} method on built instance(s).
+ * <p>
+ * Extend this class and override methods to customize, if needed.
+ *
+ * @since TBD
+ */
+public class SessionBuilderSupplier implements Supplier<SessionBuilder> {
+    protected final RepositorySystem repositorySystem;
+
+    public SessionBuilderSupplier(RepositorySystem repositorySystem) {
+        this.repositorySystem = requireNonNull(repositorySystem);
+    }
+
+    @Override
+    public SessionBuilder get() {
+        SessionBuilder builder = repositorySystem.createSessionBuilder();
+        configureSessionBuilder(builder);
+        return builder;
+    }
+
+    protected void configureSessionBuilder(SessionBuilder session) {
+        session.setDependencyTraverser(getDependencyTraverser());
+        session.setDependencyManager(getDependencyManager());
+        session.setDependencySelector(getDependencySelector());
+        session.setDependencyGraphTransformer(getDependencyGraphTransformer());
+        session.setArtifactTypeRegistry(getArtifactTypeRegistry());
+        session.setArtifactDescriptorPolicy(getArtifactDescriptorPolicy());
+    }
+
+    protected DependencyTraverser getDependencyTraverser() {
+        return new FatArtifactTraverser();
+    }
+
+    protected DependencyManager getDependencyManager() {
+        return new ClassicDependencyManager();
+    }
+
+    protected DependencySelector getDependencySelector() {
+        return new AndDependencySelector(
+                new ScopeDependencySelector("test", "provided"),
+                new OptionalDependencySelector(),
+                new ExclusionDependencySelector());
+    }
+
+    protected DependencyGraphTransformer getDependencyGraphTransformer() {
+        return new ChainedDependencyGraphTransformer(
+                new ConflictResolver(
+                        new NearestVersionSelector(), new JavaScopeSelector(),
+                        new SimpleOptionalitySelector(), new JavaScopeDeriver()),
+                new JavaDependencyContextRefiner());
+    }
+
+    protected ArtifactTypeRegistry getArtifactTypeRegistry() {
+        DefaultArtifactTypeRegistry stereotypes = new DefaultArtifactTypeRegistry();
+        stereotypes.add(new DefaultArtifactType("pom"));
+        stereotypes.add(new DefaultArtifactType("maven-plugin", "jar", "", "java"));
+        stereotypes.add(new DefaultArtifactType("jar", "jar", "", "java"));
+        stereotypes.add(new DefaultArtifactType("ejb", "jar", "", "java"));
+        stereotypes.add(new DefaultArtifactType("ejb-client", "jar", "client", "java"));
+        stereotypes.add(new DefaultArtifactType("test-jar", "jar", "tests", "java"));
+        stereotypes.add(new DefaultArtifactType("javadoc", "jar", "javadoc", "java"));
+        stereotypes.add(new DefaultArtifactType("java-source", "jar", "sources", "java", false, false));
+        stereotypes.add(new DefaultArtifactType("war", "war", "", "java", false, true));
+        stereotypes.add(new DefaultArtifactType("ear", "ear", "", "java", false, true));
+        stereotypes.add(new DefaultArtifactType("rar", "rar", "", "java", false, true));
+        stereotypes.add(new DefaultArtifactType("par", "par", "", "java", false, true));
+        return stereotypes;
+    }
+
+    protected ArtifactDescriptorPolicy getArtifactDescriptorPolicy() {
+        return new SimpleArtifactDescriptorPolicy(true, true);
+    }
+}
diff --git a/maven-resolver-supplier/src/test/java/org/eclipse/aether/supplier/RepositorySystemSupplierTest.java b/maven-resolver-supplier/src/test/java/org/eclipse/aether/supplier/RepositorySystemSupplierTest.java
index 10d08ace6..fb4301149 100644
--- a/maven-resolver-supplier/src/test/java/org/eclipse/aether/supplier/RepositorySystemSupplierTest.java
+++ b/maven-resolver-supplier/src/test/java/org/eclipse/aether/supplier/RepositorySystemSupplierTest.java
@@ -18,16 +18,14 @@
  */
 package org.eclipse.aether.supplier;
 
+import java.io.File;
 import java.util.Collections;
 import java.util.List;
 
-import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
-import org.eclipse.aether.DefaultRepositorySystemSession;
 import org.eclipse.aether.RepositorySystem;
-import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
-import org.eclipse.aether.repository.LocalRepository;
 import org.eclipse.aether.repository.RemoteRepository;
 import org.eclipse.aether.resolution.VersionRangeRequest;
 import org.eclipse.aether.resolution.VersionRangeResult;
@@ -39,28 +37,25 @@
 public class RepositorySystemSupplierTest {
     private final RepositorySystemSupplier subject = new RepositorySystemSupplier();
 
-    public static DefaultRepositorySystemSession newRepositorySystemSession(RepositorySystem system) {
-        DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
-        LocalRepository localRepo = new LocalRepository("target/local-repo");
-        session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
-        return session;
-    }
-
     @Test
     void smoke() throws Exception {
-        RepositorySystem system = subject.get();
-        RepositorySystemSession session = newRepositorySystemSession(system);
-
-        Artifact artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-util:[0,)");
-        VersionRangeRequest rangeRequest = new VersionRangeRequest();
-        rangeRequest.setArtifact(artifact);
-        rangeRequest.setRepositories(Collections.singletonList(
-                new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/").build()));
-        VersionRangeResult rangeResult = system.resolveVersionRange(session, rangeRequest);
-        List<Version> versions = rangeResult.getVersions();
-
-        // As of 2023-08-01, Maven Central has 33 versions of this artifact (and it will just grow)
-        assertTrue(versions.size() >= 33);
-        System.out.println("Available versions " + versions);
+        try (RepositorySystem system = subject.get();
+                CloseableSession session = new SessionBuilderSupplier(system)
+                        .get()
+                        .withLocalRepositoryBaseDirectories(new File("target/local-repo"))
+                        .build()) {
+            Artifact artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-util:[0,)");
+            VersionRangeRequest rangeRequest = new VersionRangeRequest();
+            rangeRequest.setArtifact(artifact);
+            rangeRequest.setRepositories(Collections.singletonList(
+                    new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2/")
+                            .build()));
+            VersionRangeResult rangeResult = system.resolveVersionRange(session, rangeRequest);
+            List<Version> versions = rangeResult.getVersions();
+
+            // As of 2023-11-14, Maven Central has 36 versions of this artifact (and it will just grow)
+            assertTrue(versions.size() >= 36);
+            System.out.println("Available " + versions.size() + " versions: " + versions);
+        }
     }
 }

From e05eaef062325738e20e3c82c1e546b3d5959e79 Mon Sep 17 00:00:00 2001
From: Tamas Cservenak <tamas@cservenak.net>
Date: Tue, 14 Nov 2023 15:17:46 +0100
Subject: [PATCH 2/5] Add javadoc, tidy up, reshuffle methods

---
 .../supplier/SessionBuilderSupplier.java      | 24 +++++++++++++------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/maven-resolver-supplier/src/main/java/org/eclipse/aether/supplier/SessionBuilderSupplier.java b/maven-resolver-supplier/src/main/java/org/eclipse/aether/supplier/SessionBuilderSupplier.java
index e3163ef7c..9cca7da48 100644
--- a/maven-resolver-supplier/src/main/java/org/eclipse/aether/supplier/SessionBuilderSupplier.java
+++ b/maven-resolver-supplier/src/main/java/org/eclipse/aether/supplier/SessionBuilderSupplier.java
@@ -64,13 +64,6 @@ public SessionBuilderSupplier(RepositorySystem repositorySystem) {
         this.repositorySystem = requireNonNull(repositorySystem);
     }
 
-    @Override
-    public SessionBuilder get() {
-        SessionBuilder builder = repositorySystem.createSessionBuilder();
-        configureSessionBuilder(builder);
-        return builder;
-    }
-
     protected void configureSessionBuilder(SessionBuilder session) {
         session.setDependencyTraverser(getDependencyTraverser());
         session.setDependencyManager(getDependencyManager());
@@ -123,4 +116,21 @@ protected ArtifactTypeRegistry getArtifactTypeRegistry() {
     protected ArtifactDescriptorPolicy getArtifactDescriptorPolicy() {
         return new SimpleArtifactDescriptorPolicy(true, true);
     }
+
+    /**
+     * Creates a new Maven-like repository system session by initializing the session with values typical for
+     * Maven-based resolution. In more detail, this method configures settings relevant for the processing of dependency
+     * graphs, most other settings remain at their generic default value. Use the various setters to further configure
+     * the session with authentication, mirror, proxy and other information required for your environment. At least,
+     * local repository manager needs to be configured to make session be able to create session instance.
+     *
+     * @return SessionBuilder configured with minimally required things for "Maven-based resolution". At least LRM must
+     * be set on builder to make it able to create session instances.
+     */
+    @Override
+    public SessionBuilder get() {
+        SessionBuilder builder = repositorySystem.createSessionBuilder();
+        configureSessionBuilder(builder);
+        return builder;
+    }
 }

From 3b680d611ed849bc0d76e9d84dde2b12e72a39a6 Mon Sep 17 00:00:00 2001
From: Tamas Cservenak <tamas@cservenak.net>
Date: Tue, 14 Nov 2023 16:49:52 +0100
Subject: [PATCH 3/5] Convert all the demos to v2 session handling.

Fixed bugs:
* builder was building _same instance_ over and over again
* improved data and sessionId handling.
---
 .../DependencyHierarchyWithRanges.java        | 51 +++++++++---------
 .../resolver/examples/DeployArtifacts.java    | 38 ++++++-------
 .../examples/FindAvailableVersions.java       | 24 ++++-----
 .../resolver/examples/FindNewestVersion.java  | 26 ++++-----
 .../examples/GetDependencyHierarchy.java      | 41 +++++++-------
 .../resolver/examples/GetDependencyTree.java  | 22 ++++----
 .../examples/GetDirectDependencies.java       | 24 ++++-----
 .../resolver/examples/InstallArtifacts.java   | 26 ++++-----
 .../resolver/examples/ResolveArtifact.java    | 53 ++++++++++---------
 .../ResolveTransitiveDependencies.java        | 32 +++++------
 .../examples/ReverseDependencyTree.java       | 53 ++++++++++---------
 .../resolver/examples/resolver/Resolver.java  | 11 ++--
 .../maven/resolver/examples/util/Booter.java  | 23 ++++----
 .../impl/DefaultRepositorySystem.java         |  2 +-
 .../impl/session/DefaultSessionBuilder.java   | 28 ++++++++--
 15 files changed, 236 insertions(+), 218 deletions(-)

diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/DependencyHierarchyWithRanges.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/DependencyHierarchyWithRanges.java
index 19820f59f..56aa2a539 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/DependencyHierarchyWithRanges.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/DependencyHierarchyWithRanges.java
@@ -22,8 +22,9 @@
 import java.util.Collections;
 
 import org.apache.maven.resolver.examples.util.Booter;
-import org.eclipse.aether.DefaultRepositorySystemSession;
 import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
+import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.collection.CollectRequest;
@@ -51,34 +52,34 @@ public static void main(String[] args) throws Exception {
         System.out.println("------------------------------------------------------------");
         System.out.println(DependencyHierarchyWithRanges.class.getSimpleName());
 
-        RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+        try (RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args))) {
+            SessionBuilder sessionBuilder = Booter.newRepositorySystemSession(system);
+            sessionBuilder.setChecksumPolicy(RepositoryPolicy.CHECKSUM_POLICY_IGNORE); // to not bother with checksums
+            sessionBuilder.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true);
+            sessionBuilder.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
+            try (CloseableSession session = sessionBuilder.build()) {
+                // this artifact is in "remote" repository in src/main/remote-repository
+                Artifact artifact = new DefaultArtifact("org.apache.maven.resolver.demo.mresolver345:a:1.0");
 
-        DefaultRepositorySystemSession session = Booter.newRepositorySystemSession(system);
+                File remoteRepoBasedir = new File("src/main/remote-repository");
 
-        session.setChecksumPolicy(RepositoryPolicy.CHECKSUM_POLICY_IGNORE); // to not bother with checksums
-        session.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true);
-        session.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
+                ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
+                descriptorRequest.setArtifact(artifact);
+                descriptorRequest.setRepositories(Collections.singletonList(new RemoteRepository.Builder(
+                                "remote", "default", remoteRepoBasedir.toURI().toASCIIString())
+                        .build()));
+                ArtifactDescriptorResult descriptorResult = system.readArtifactDescriptor(session, descriptorRequest);
 
-        // this artifact is in "remote" repository in src/main/remote-repository
-        Artifact artifact = new DefaultArtifact("org.apache.maven.resolver.demo.mresolver345:a:1.0");
+                CollectRequest collectRequest = new CollectRequest();
+                collectRequest.setRootArtifact(descriptorResult.getArtifact());
+                collectRequest.setDependencies(descriptorResult.getDependencies());
+                collectRequest.setManagedDependencies(descriptorResult.getManagedDependencies());
+                collectRequest.setRepositories(descriptorRequest.getRepositories());
 
-        File remoteRepoBasedir = new File("src/main/remote-repository");
+                CollectResult collectResult = system.collectDependencies(session, collectRequest);
 
-        ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
-        descriptorRequest.setArtifact(artifact);
-        descriptorRequest.setRepositories(Collections.singletonList(new RemoteRepository.Builder(
-                        "remote", "default", remoteRepoBasedir.toURI().toASCIIString())
-                .build()));
-        ArtifactDescriptorResult descriptorResult = system.readArtifactDescriptor(session, descriptorRequest);
-
-        CollectRequest collectRequest = new CollectRequest();
-        collectRequest.setRootArtifact(descriptorResult.getArtifact());
-        collectRequest.setDependencies(descriptorResult.getDependencies());
-        collectRequest.setManagedDependencies(descriptorResult.getManagedDependencies());
-        collectRequest.setRepositories(descriptorRequest.getRepositories());
-
-        CollectResult collectResult = system.collectDependencies(session, collectRequest);
-
-        collectResult.getRoot().accept(Booter.DUMPER_SOUT);
+                collectResult.getRoot().accept(Booter.DUMPER_SOUT);
+            }
+        }
     }
 }
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/DeployArtifacts.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/DeployArtifacts.java
index 5f26c112c..e06f7b6e3 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/DeployArtifacts.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/DeployArtifacts.java
@@ -22,7 +22,7 @@
 
 import org.apache.maven.resolver.examples.util.Booter;
 import org.eclipse.aether.RepositorySystem;
-import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.deployment.DeployRequest;
@@ -43,27 +43,27 @@ public static void main(String[] args) throws Exception {
         System.out.println("------------------------------------------------------------");
         System.out.println(DeployArtifacts.class.getSimpleName());
 
-        RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+        try (RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+                CloseableSession session =
+                        Booter.newRepositorySystemSession(system).build()) {
+            Artifact jarArtifact =
+                    new DefaultArtifact("test", "org.apache.maven.aether.examples", "", "jar", "0.1-SNAPSHOT");
+            jarArtifact = jarArtifact.setFile(new File("src/main/data/demo.jar"));
 
-        RepositorySystemSession session = Booter.newRepositorySystemSession(system);
+            Artifact pomArtifact = new SubArtifact(jarArtifact, "", "pom");
+            pomArtifact = pomArtifact.setFile(new File("pom.xml"));
 
-        Artifact jarArtifact =
-                new DefaultArtifact("test", "org.apache.maven.aether.examples", "", "jar", "0.1-SNAPSHOT");
-        jarArtifact = jarArtifact.setFile(new File("src/main/data/demo.jar"));
+            RemoteRepository distRepo = new RemoteRepository.Builder(
+                            "org.apache.maven.aether.examples",
+                            "default",
+                            new File("target/dist-repo").toURI().toString())
+                    .build();
 
-        Artifact pomArtifact = new SubArtifact(jarArtifact, "", "pom");
-        pomArtifact = pomArtifact.setFile(new File("pom.xml"));
+            DeployRequest deployRequest = new DeployRequest();
+            deployRequest.addArtifact(jarArtifact).addArtifact(pomArtifact);
+            deployRequest.setRepository(distRepo);
 
-        RemoteRepository distRepo = new RemoteRepository.Builder(
-                        "org.apache.maven.aether.examples",
-                        "default",
-                        new File("target/dist-repo").toURI().toString())
-                .build();
-
-        DeployRequest deployRequest = new DeployRequest();
-        deployRequest.addArtifact(jarArtifact).addArtifact(pomArtifact);
-        deployRequest.setRepository(distRepo);
-
-        system.deploy(session, deployRequest);
+            system.deploy(session, deployRequest);
+        }
     }
 }
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/FindAvailableVersions.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/FindAvailableVersions.java
index c82cb27e6..ced5cad09 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/FindAvailableVersions.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/FindAvailableVersions.java
@@ -22,7 +22,7 @@
 
 import org.apache.maven.resolver.examples.util.Booter;
 import org.eclipse.aether.RepositorySystem;
-import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.resolution.VersionRangeRequest;
@@ -43,20 +43,20 @@ public static void main(String[] args) throws Exception {
         System.out.println("------------------------------------------------------------");
         System.out.println(FindAvailableVersions.class.getSimpleName());
 
-        RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+        try (RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+                CloseableSession session =
+                        Booter.newRepositorySystemSession(system).build()) {
+            Artifact artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-util:[0,)");
 
-        RepositorySystemSession session = Booter.newRepositorySystemSession(system);
+            VersionRangeRequest rangeRequest = new VersionRangeRequest();
+            rangeRequest.setArtifact(artifact);
+            rangeRequest.setRepositories(Booter.newRepositories(system, session));
 
-        Artifact artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-util:[0,)");
+            VersionRangeResult rangeResult = system.resolveVersionRange(session, rangeRequest);
 
-        VersionRangeRequest rangeRequest = new VersionRangeRequest();
-        rangeRequest.setArtifact(artifact);
-        rangeRequest.setRepositories(Booter.newRepositories(system, session));
+            List<Version> versions = rangeResult.getVersions();
 
-        VersionRangeResult rangeResult = system.resolveVersionRange(session, rangeRequest);
-
-        List<Version> versions = rangeResult.getVersions();
-
-        System.out.println("Available versions " + versions);
+            System.out.println("Available versions " + versions);
+        }
     }
 }
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/FindNewestVersion.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/FindNewestVersion.java
index 7cebfd24b..c92e9b369 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/FindNewestVersion.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/FindNewestVersion.java
@@ -20,7 +20,7 @@
 
 import org.apache.maven.resolver.examples.util.Booter;
 import org.eclipse.aether.RepositorySystem;
-import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.resolution.VersionRangeRequest;
@@ -40,21 +40,21 @@ public static void main(String[] args) throws Exception {
         System.out.println("------------------------------------------------------------");
         System.out.println(FindNewestVersion.class.getSimpleName());
 
-        RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+        try (RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+                CloseableSession session =
+                        Booter.newRepositorySystemSession(system).build()) {
+            Artifact artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-util:[0,)");
 
-        RepositorySystemSession session = Booter.newRepositorySystemSession(system);
+            VersionRangeRequest rangeRequest = new VersionRangeRequest();
+            rangeRequest.setArtifact(artifact);
+            rangeRequest.setRepositories(Booter.newRepositories(system, session));
 
-        Artifact artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-util:[0,)");
+            VersionRangeResult rangeResult = system.resolveVersionRange(session, rangeRequest);
 
-        VersionRangeRequest rangeRequest = new VersionRangeRequest();
-        rangeRequest.setArtifact(artifact);
-        rangeRequest.setRepositories(Booter.newRepositories(system, session));
+            Version newestVersion = rangeResult.getHighestVersion();
 
-        VersionRangeResult rangeResult = system.resolveVersionRange(session, rangeRequest);
-
-        Version newestVersion = rangeResult.getHighestVersion();
-
-        System.out.println(
-                "Newest version " + newestVersion + " from repository " + rangeResult.getRepository(newestVersion));
+            System.out.println(
+                    "Newest version " + newestVersion + " from repository " + rangeResult.getRepository(newestVersion));
+        }
     }
 }
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/GetDependencyHierarchy.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/GetDependencyHierarchy.java
index 3a4504d74..a865f4d51 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/GetDependencyHierarchy.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/GetDependencyHierarchy.java
@@ -19,8 +19,9 @@
 package org.apache.maven.resolver.examples;
 
 import org.apache.maven.resolver.examples.util.Booter;
-import org.eclipse.aether.DefaultRepositorySystemSession;
 import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
+import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.collection.CollectRequest;
@@ -44,28 +45,28 @@ public static void main(String[] args) throws Exception {
         System.out.println("------------------------------------------------------------");
         System.out.println(GetDependencyHierarchy.class.getSimpleName());
 
-        RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+        try (RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args))) {
+            SessionBuilder sessionBuilder = Booter.newRepositorySystemSession(system);
+            sessionBuilder.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true);
+            sessionBuilder.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
+            try (CloseableSession session = sessionBuilder.build()) {
+                Artifact artifact = new DefaultArtifact("org.apache.maven:maven-resolver-provider:3.6.1");
 
-        DefaultRepositorySystemSession session = Booter.newRepositorySystemSession(system);
+                ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
+                descriptorRequest.setArtifact(artifact);
+                descriptorRequest.setRepositories(Booter.newRepositories(system, session));
+                ArtifactDescriptorResult descriptorResult = system.readArtifactDescriptor(session, descriptorRequest);
 
-        session.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true);
-        session.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
+                CollectRequest collectRequest = new CollectRequest();
+                collectRequest.setRootArtifact(descriptorResult.getArtifact());
+                collectRequest.setDependencies(descriptorResult.getDependencies());
+                collectRequest.setManagedDependencies(descriptorResult.getManagedDependencies());
+                collectRequest.setRepositories(descriptorRequest.getRepositories());
 
-        Artifact artifact = new DefaultArtifact("org.apache.maven:maven-resolver-provider:3.6.1");
+                CollectResult collectResult = system.collectDependencies(session, collectRequest);
 
-        ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
-        descriptorRequest.setArtifact(artifact);
-        descriptorRequest.setRepositories(Booter.newRepositories(system, session));
-        ArtifactDescriptorResult descriptorResult = system.readArtifactDescriptor(session, descriptorRequest);
-
-        CollectRequest collectRequest = new CollectRequest();
-        collectRequest.setRootArtifact(descriptorResult.getArtifact());
-        collectRequest.setDependencies(descriptorResult.getDependencies());
-        collectRequest.setManagedDependencies(descriptorResult.getManagedDependencies());
-        collectRequest.setRepositories(descriptorRequest.getRepositories());
-
-        CollectResult collectResult = system.collectDependencies(session, collectRequest);
-
-        collectResult.getRoot().accept(Booter.DUMPER_SOUT);
+                collectResult.getRoot().accept(Booter.DUMPER_SOUT);
+            }
+        }
     }
 }
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/GetDependencyTree.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/GetDependencyTree.java
index 77042e40e..dd2ed02ce 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/GetDependencyTree.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/GetDependencyTree.java
@@ -20,7 +20,7 @@
 
 import org.apache.maven.resolver.examples.util.Booter;
 import org.eclipse.aether.RepositorySystem;
-import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.collection.CollectRequest;
@@ -41,18 +41,18 @@ public static void main(String[] args) throws Exception {
         System.out.println("------------------------------------------------------------");
         System.out.println(GetDependencyTree.class.getSimpleName());
 
-        RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+        try (RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+                CloseableSession session =
+                        Booter.newRepositorySystemSession(system).build()) {
+            Artifact artifact = new DefaultArtifact("org.apache.maven:maven-resolver-provider:3.6.1");
 
-        RepositorySystemSession session = Booter.newRepositorySystemSession(system);
+            CollectRequest collectRequest = new CollectRequest();
+            collectRequest.setRoot(new Dependency(artifact, ""));
+            collectRequest.setRepositories(Booter.newRepositories(system, session));
 
-        Artifact artifact = new DefaultArtifact("org.apache.maven:maven-resolver-provider:3.6.1");
+            CollectResult collectResult = system.collectDependencies(session, collectRequest);
 
-        CollectRequest collectRequest = new CollectRequest();
-        collectRequest.setRoot(new Dependency(artifact, ""));
-        collectRequest.setRepositories(Booter.newRepositories(system, session));
-
-        CollectResult collectResult = system.collectDependencies(session, collectRequest);
-
-        collectResult.getRoot().accept(Booter.DUMPER_SOUT);
+            collectResult.getRoot().accept(Booter.DUMPER_SOUT);
+        }
     }
 }
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/GetDirectDependencies.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/GetDirectDependencies.java
index 7fcda35a6..5e82a44b0 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/GetDirectDependencies.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/GetDirectDependencies.java
@@ -20,7 +20,7 @@
 
 import org.apache.maven.resolver.examples.util.Booter;
 import org.eclipse.aether.RepositorySystem;
-import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.graph.Dependency;
@@ -41,20 +41,20 @@ public static void main(String[] args) throws Exception {
         System.out.println("------------------------------------------------------------");
         System.out.println(GetDirectDependencies.class.getSimpleName());
 
-        RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+        try (RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+                CloseableSession session =
+                        Booter.newRepositorySystemSession(system).build()) {
+            Artifact artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-impl:1.3.3");
 
-        RepositorySystemSession session = Booter.newRepositorySystemSession(system);
+            ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
+            descriptorRequest.setArtifact(artifact);
+            descriptorRequest.setRepositories(Booter.newRepositories(system, session));
 
-        Artifact artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-impl:1.3.3");
+            ArtifactDescriptorResult descriptorResult = system.readArtifactDescriptor(session, descriptorRequest);
 
-        ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
-        descriptorRequest.setArtifact(artifact);
-        descriptorRequest.setRepositories(Booter.newRepositories(system, session));
-
-        ArtifactDescriptorResult descriptorResult = system.readArtifactDescriptor(session, descriptorRequest);
-
-        for (Dependency dependency : descriptorResult.getDependencies()) {
-            System.out.println(dependency);
+            for (Dependency dependency : descriptorResult.getDependencies()) {
+                System.out.println(dependency);
+            }
         }
     }
 }
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/InstallArtifacts.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/InstallArtifacts.java
index 7e2916365..b06c34e19 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/InstallArtifacts.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/InstallArtifacts.java
@@ -22,7 +22,7 @@
 
 import org.apache.maven.resolver.examples.util.Booter;
 import org.eclipse.aether.RepositorySystem;
-import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.installation.InstallRequest;
@@ -42,20 +42,20 @@ public static void main(String[] args) throws Exception {
         System.out.println("------------------------------------------------------------");
         System.out.println(InstallArtifacts.class.getSimpleName());
 
-        RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+        try (RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+                CloseableSession session =
+                        Booter.newRepositorySystemSession(system).build()) {
+            Artifact jarArtifact =
+                    new DefaultArtifact("test", "org.apache.maven.resolver.examples", "", "jar", "0.1-SNAPSHOT");
+            jarArtifact = jarArtifact.setFile(new File("src/main/data/demo.jar"));
 
-        RepositorySystemSession session = Booter.newRepositorySystemSession(system);
+            Artifact pomArtifact = new SubArtifact(jarArtifact, "", "pom");
+            pomArtifact = pomArtifact.setFile(new File("pom.xml"));
 
-        Artifact jarArtifact =
-                new DefaultArtifact("test", "org.apache.maven.resolver.examples", "", "jar", "0.1-SNAPSHOT");
-        jarArtifact = jarArtifact.setFile(new File("src/main/data/demo.jar"));
+            InstallRequest installRequest = new InstallRequest();
+            installRequest.addArtifact(jarArtifact).addArtifact(pomArtifact);
 
-        Artifact pomArtifact = new SubArtifact(jarArtifact, "", "pom");
-        pomArtifact = pomArtifact.setFile(new File("pom.xml"));
-
-        InstallRequest installRequest = new InstallRequest();
-        installRequest.addArtifact(jarArtifact).addArtifact(pomArtifact);
-
-        system.install(session, installRequest);
+            system.install(session, installRequest);
+        }
     }
 }
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/ResolveArtifact.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/ResolveArtifact.java
index 0359c6e1a..cbc81d080 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/ResolveArtifact.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/ResolveArtifact.java
@@ -19,8 +19,9 @@
 package org.apache.maven.resolver.examples;
 
 import org.apache.maven.resolver.examples.util.Booter;
-import org.eclipse.aether.DefaultRepositorySystemSession;
 import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.repository.RepositoryPolicy;
@@ -41,40 +42,42 @@ public static void main(String[] args) throws Exception {
         System.out.println("------------------------------------------------------------");
         System.out.println(ResolveArtifact.class.getSimpleName());
 
-        RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+        try (RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args))) {
+            RepositorySystemSession.SessionBuilder sessionBuilder = Booter.newRepositorySystemSession(system);
+            Artifact artifact;
+            ArtifactRequest artifactRequest;
+            ArtifactResult artifactResult;
 
-        DefaultRepositorySystemSession session = Booter.newRepositorySystemSession(system);
+            try (CloseableSession session = sessionBuilder.build()) {
+                artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-util:1.3.3");
 
-        Artifact artifact;
-        ArtifactRequest artifactRequest;
-        ArtifactResult artifactResult;
+                artifactRequest = new ArtifactRequest();
+                artifactRequest.setArtifact(artifact);
+                artifactRequest.setRepositories(Booter.newRepositories(system, session));
 
-        // artifact
-        artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-util:1.3.3");
+                artifactResult = system.resolveArtifact(session, artifactRequest);
 
-        artifactRequest = new ArtifactRequest();
-        artifactRequest.setArtifact(artifact);
-        artifactRequest.setRepositories(Booter.newRepositories(system, session));
+                artifact = artifactResult.getArtifact();
 
-        artifactResult = system.resolveArtifact(session, artifactRequest);
+                System.out.println(artifact + " resolved to  " + artifact.getFile());
+            }
 
-        artifact = artifactResult.getArtifact();
+            // signature
+            sessionBuilder.setChecksumPolicy(RepositoryPolicy.CHECKSUM_POLICY_FAIL);
 
-        System.out.println(artifact + " resolved to  " + artifact.getFile());
+            try (CloseableSession session = sessionBuilder.build()) {
+                artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-util:jar.asc:1.3.3");
 
-        // signature
-        session.setChecksumPolicy(RepositoryPolicy.CHECKSUM_POLICY_FAIL);
+                artifactRequest = new ArtifactRequest();
+                artifactRequest.setArtifact(artifact);
+                artifactRequest.setRepositories(Booter.newRepositories(system, session));
 
-        artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-util:jar.asc:1.3.3");
+                artifactResult = system.resolveArtifact(session, artifactRequest);
 
-        artifactRequest = new ArtifactRequest();
-        artifactRequest.setArtifact(artifact);
-        artifactRequest.setRepositories(Booter.newRepositories(system, session));
+                artifact = artifactResult.getArtifact();
 
-        artifactResult = system.resolveArtifact(session, artifactRequest);
-
-        artifact = artifactResult.getArtifact();
-
-        System.out.println(artifact + " resolved signature to  " + artifact.getFile());
+                System.out.println(artifact + " resolved signature to  " + artifact.getFile());
+            }
+        }
     }
 }
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/ResolveTransitiveDependencies.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/ResolveTransitiveDependencies.java
index a9541b052..35c215b2c 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/ResolveTransitiveDependencies.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/ResolveTransitiveDependencies.java
@@ -22,7 +22,7 @@
 
 import org.apache.maven.resolver.examples.util.Booter;
 import org.eclipse.aether.RepositorySystem;
-import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.collection.CollectRequest;
@@ -47,26 +47,26 @@ public static void main(String[] args) throws Exception {
         System.out.println("------------------------------------------------------------");
         System.out.println(ResolveTransitiveDependencies.class.getSimpleName());
 
-        RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+        try (RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+                CloseableSession session =
+                        Booter.newRepositorySystemSession(system).build()) {
+            Artifact artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-impl:1.3.3");
 
-        RepositorySystemSession session = Booter.newRepositorySystemSession(system);
+            DependencyFilter classpathFlter = DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE);
 
-        Artifact artifact = new DefaultArtifact("org.apache.maven.resolver:maven-resolver-impl:1.3.3");
+            CollectRequest collectRequest = new CollectRequest();
+            collectRequest.setRoot(new Dependency(artifact, JavaScopes.COMPILE));
+            collectRequest.setRepositories(Booter.newRepositories(system, session));
 
-        DependencyFilter classpathFlter = DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE);
+            DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, classpathFlter);
 
-        CollectRequest collectRequest = new CollectRequest();
-        collectRequest.setRoot(new Dependency(artifact, JavaScopes.COMPILE));
-        collectRequest.setRepositories(Booter.newRepositories(system, session));
+            List<ArtifactResult> artifactResults =
+                    system.resolveDependencies(session, dependencyRequest).getArtifactResults();
 
-        DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, classpathFlter);
-
-        List<ArtifactResult> artifactResults =
-                system.resolveDependencies(session, dependencyRequest).getArtifactResults();
-
-        for (ArtifactResult artifactResult : artifactResults) {
-            System.out.println(artifactResult.getArtifact() + " resolved to "
-                    + artifactResult.getArtifact().getFile());
+            for (ArtifactResult artifactResult : artifactResults) {
+                System.out.println(artifactResult.getArtifact() + " resolved to "
+                        + artifactResult.getArtifact().getFile());
+            }
         }
     }
 }
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/ReverseDependencyTree.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/ReverseDependencyTree.java
index 663b26ccb..7a9d95f22 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/ReverseDependencyTree.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/ReverseDependencyTree.java
@@ -20,8 +20,9 @@
 
 import org.apache.maven.resolver.examples.util.Booter;
 import org.apache.maven.resolver.examples.util.ReverseTreeRepositoryListener;
-import org.eclipse.aether.DefaultRepositorySystemSession;
 import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession.CloseableSession;
+import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.collection.CollectRequest;
@@ -45,34 +46,34 @@ public static void main(String[] args) throws Exception {
         System.out.println("------------------------------------------------------------");
         System.out.println(ReverseDependencyTree.class.getSimpleName());
 
-        RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args));
+        try (RepositorySystem system = Booter.newRepositorySystem(Booter.selectFactory(args))) {
+            SessionBuilder sessionBuilder = Booter.newRepositorySystemSession(system);
+            try (CloseableSession session = sessionBuilder.build()) {
+                sessionBuilder.setRepositoryListener(new ChainedRepositoryListener(
+                        session.getRepositoryListener(), new ReverseTreeRepositoryListener()));
+            }
+            sessionBuilder.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true);
+            sessionBuilder.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
+            try (CloseableSession session = sessionBuilder.build()) {
+                Artifact artifact = new DefaultArtifact("org.apache.maven:maven-resolver-provider:3.6.1");
 
-        DefaultRepositorySystemSession session = Booter.newRepositorySystemSession(system);
+                ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
+                descriptorRequest.setArtifact(artifact);
+                descriptorRequest.setRepositories(Booter.newRepositories(system, session));
+                ArtifactDescriptorResult descriptorResult = system.readArtifactDescriptor(session, descriptorRequest);
 
-        // install the listener into session
-        session.setRepositoryListener(
-                new ChainedRepositoryListener(session.getRepositoryListener(), new ReverseTreeRepositoryListener()));
+                CollectRequest collectRequest = new CollectRequest();
+                collectRequest.setRequestContext("demo");
+                collectRequest.setRootArtifact(descriptorResult.getArtifact());
+                collectRequest.setDependencies(descriptorResult.getDependencies());
+                collectRequest.setManagedDependencies(descriptorResult.getManagedDependencies());
+                collectRequest.setRepositories(descriptorRequest.getRepositories());
 
-        session.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true);
-        session.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
+                system.collectDependencies(session, collectRequest);
 
-        Artifact artifact = new DefaultArtifact("org.apache.maven:maven-resolver-provider:3.6.1");
-
-        ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
-        descriptorRequest.setArtifact(artifact);
-        descriptorRequest.setRepositories(Booter.newRepositories(system, session));
-        ArtifactDescriptorResult descriptorResult = system.readArtifactDescriptor(session, descriptorRequest);
-
-        CollectRequest collectRequest = new CollectRequest();
-        collectRequest.setRequestContext("demo");
-        collectRequest.setRootArtifact(descriptorResult.getArtifact());
-        collectRequest.setDependencies(descriptorResult.getDependencies());
-        collectRequest.setManagedDependencies(descriptorResult.getManagedDependencies());
-        collectRequest.setRepositories(descriptorRequest.getRepositories());
-
-        system.collectDependencies(session, collectRequest);
-
-        // in this demo we are not interested in collect result,
-        // as all the "demo work" is done by installed ReverseTreeRepositoryListener
+                // in this demo we are not interested in collect result,
+                // as all the "demo work" is done by installed ReverseTreeRepositoryListener
+            }
+        }
     }
 }
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/resolver/Resolver.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/resolver/Resolver.java
index d54388721..a3c9b8fe7 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/resolver/Resolver.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/resolver/Resolver.java
@@ -24,7 +24,6 @@
 import java.nio.charset.StandardCharsets;
 
 import org.apache.maven.resolver.examples.util.Booter;
-import org.eclipse.aether.DefaultRepositorySystemSession;
 import org.eclipse.aether.RepositorySystem;
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.artifact.Artifact;
@@ -62,11 +61,11 @@ public Resolver(String factory, String remoteRepository, String localRepository)
     }
 
     private RepositorySystemSession newSession() {
-        DefaultRepositorySystemSession session = Booter.newRepositorySystemSession(repositorySystem);
-        session.setLocalRepositoryManager(repositorySystem.newLocalRepositoryManager(session, localRepository));
-        session.setTransferListener(null);
-        session.setRepositoryListener(null);
-        return session;
+        return Booter.newRepositorySystemSession(repositorySystem)
+                .withLocalRepositories(localRepository)
+                .setRepositoryListener(null)
+                .setTransferListener(null)
+                .build();
     }
 
     public ResolverResult resolve(String groupId, String artifactId, String version)
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/util/Booter.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/util/Booter.java
index c74cda0fb..4ec87581b 100644
--- a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/util/Booter.java
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/org/apache/maven/resolver/examples/util/Booter.java
@@ -18,16 +18,16 @@
  */
 package org.apache.maven.resolver.examples.util;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
-import org.eclipse.aether.DefaultRepositorySystemSession;
 import org.eclipse.aether.RepositorySystem;
 import org.eclipse.aether.RepositorySystemSession;
-import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
 import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.supplier.SessionBuilderSupplier;
 import org.eclipse.aether.util.graph.visitor.DependencyGraphDumper;
 
 /**
@@ -60,19 +60,14 @@ public static RepositorySystem newRepositorySystem(final String factory) {
         }
     }
 
-    public static DefaultRepositorySystemSession newRepositorySystemSession(RepositorySystem system) {
-        DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
-
-        LocalRepository localRepo = new LocalRepository("target/local-repo");
-        session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
-
-        session.setTransferListener(new ConsoleTransferListener());
-        session.setRepositoryListener(new ConsoleRepositoryListener());
-
+    public static SessionBuilder newRepositorySystemSession(RepositorySystem system) {
+        return new SessionBuilderSupplier(system)
+                .get()
+                .withLocalRepositoryBaseDirectories(new File("target/local-repo"))
+                .setRepositoryListener(new ConsoleRepositoryListener())
+                .setTransferListener(new ConsoleTransferListener());
         // uncomment to generate dirty trees
         // session.setDependencyGraphTransformer( null );
-
-        return session;
     }
 
     public static List<RemoteRepository> newRepositories(RepositorySystem system, RepositorySystemSession session) {
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultRepositorySystem.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultRepositorySystem.java
index eaba59598..944a9539b 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultRepositorySystem.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultRepositorySystem.java
@@ -404,7 +404,7 @@ public void addOnSystemEndedHandler(Runnable handler) {
     public RepositorySystemSession.SessionBuilder createSessionBuilder() {
         validateSystem();
         return new DefaultSessionBuilder(
-                this, repositorySystemLifecycle, "id-" + sessionIdCounter.incrementAndGet(), null);
+                this, repositorySystemLifecycle, () -> "id-" + sessionIdCounter.incrementAndGet());
     }
 
     @Override
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultSessionBuilder.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultSessionBuilder.java
index 70911608f..5052bbf42 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultSessionBuilder.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultSessionBuilder.java
@@ -24,6 +24,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Supplier;
 
 import org.eclipse.aether.DefaultSessionData;
 import org.eclipse.aether.RepositoryCache;
@@ -70,7 +71,7 @@ public final class DefaultSessionBuilder implements SessionBuilder {
 
     private final RepositorySystemLifecycle repositorySystemLifecycle;
 
-    private final String sessionId;
+    private final Supplier<String> sessionIdSupplier;
 
     private final AtomicBoolean closed;
 
@@ -122,18 +123,35 @@ public final class DefaultSessionBuilder implements SessionBuilder {
 
     private DependencyGraphTransformer dependencyGraphTransformer;
 
-    private SessionData data = new DefaultSessionData();
+    private SessionData data;
 
     private RepositoryCache cache;
 
+    /**
+     * Constructor for "top level" builders.
+     */
     public DefaultSessionBuilder(
+            RepositorySystem repositorySystem,
+            RepositorySystemLifecycle repositorySystemLifecycle,
+            Supplier<String> sessionIdSupplier) {
+        this.repositorySystem = requireNonNull(repositorySystem);
+        this.repositorySystemLifecycle = requireNonNull(repositorySystemLifecycle);
+        this.sessionIdSupplier = requireNonNull(sessionIdSupplier);
+        this.closed = null;
+    }
+
+    /**
+     * "Copy constructor" used by {@link DefaultCloseableSession#copy()}. It carries over session ID and builder will
+     * create same ID sessions.
+     */
+    DefaultSessionBuilder(
             RepositorySystem repositorySystem,
             RepositorySystemLifecycle repositorySystemLifecycle,
             String sessionId,
             AtomicBoolean closed) {
         this.repositorySystem = requireNonNull(repositorySystem);
         this.repositorySystemLifecycle = requireNonNull(repositorySystemLifecycle);
-        this.sessionId = requireNonNull(sessionId);
+        this.sessionIdSupplier = () -> sessionId;
         this.closed = closed;
     }
 
@@ -397,7 +415,7 @@ public SessionBuilder withRepositorySystemSession(RepositorySystemSession sessio
     @Override
     public CloseableSession build() {
         return new DefaultCloseableSession(
-                sessionId,
+                sessionIdSupplier.get(),
                 closed,
                 offline,
                 ignoreArtifactDescriptorRepositories,
@@ -423,7 +441,7 @@ public CloseableSession build() {
                 dependencySelector,
                 versionFilter,
                 dependencyGraphTransformer,
-                data,
+                data != null ? data : new DefaultSessionData(),
                 cache,
                 repositorySystem,
                 repositorySystemLifecycle);

From e54358b889c944eddc4b89c3dad71ae560468a15 Mon Sep 17 00:00:00 2001
From: Tamas Cservenak <tamas@cservenak.net>
Date: Tue, 14 Nov 2023 17:08:29 +0100
Subject: [PATCH 4/5] Add warning about builder in javadoc

Also fix shared properties, another bug in builder.
---
 .../org/eclipse/aether/RepositorySystemSession.java    | 10 ++++++----
 .../internal/impl/session/DefaultSessionBuilder.java   |  6 +++---
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/RepositorySystemSession.java b/maven-resolver-api/src/main/java/org/eclipse/aether/RepositorySystemSession.java
index bf7a8f52c..189fd15d5 100644
--- a/maven-resolver-api/src/main/java/org/eclipse/aether/RepositorySystemSession.java
+++ b/maven-resolver-api/src/main/java/org/eclipse/aether/RepositorySystemSession.java
@@ -94,6 +94,10 @@ interface CloseableSession extends RepositorySystemSession, Closeable {
     /**
      * Builder for building {@link CloseableSession} instances. Builder instances can be created with
      * {@link RepositorySystem#createSessionBuilder()} method. Instances are not thread-safe nor immutable.
+     * <p>
+     * Important: if you set a stateful member on builder (for example {@link SessionData} or {@link RepositoryCache}),
+     * the builder will create session instances using same provided stateful members, that may lead to unexpected side
+     * effects. Solution for these cases is to not reuse builder instances.
      *
      * @noimplement This interface is not intended to be implemented by clients.
      * @noextend This interface is not intended to be extended by clients.
@@ -399,7 +403,7 @@ interface SessionBuilder {
          *
          * @param baseDirectories The local repository base directories.
          * @return This session for chaining, never {@code null}.
-         * @see #newLocalRepositoryManager(LocalRepository...)
+         * @see #withLocalRepositories(LocalRepository...)
          */
         SessionBuilder withLocalRepositoryBaseDirectories(File... baseDirectories);
 
@@ -410,7 +414,7 @@ interface SessionBuilder {
          *
          * @param baseDirectories The local repository base directories.
          * @return This session for chaining, never {@code null}.
-         * @see #newLocalRepositoryManager(LocalRepository...)
+         * @see #withLocalRepositories(List)
          */
         SessionBuilder withLocalRepositoryBaseDirectories(List<File> baseDirectories);
 
@@ -421,7 +425,6 @@ interface SessionBuilder {
          *
          * @param localRepositories The local repositories.
          * @return This session for chaining, never {@code null}.
-         * @see #newLocalRepositoryManager(LocalRepository...)
          */
         SessionBuilder withLocalRepositories(LocalRepository... localRepositories);
 
@@ -432,7 +435,6 @@ interface SessionBuilder {
          *
          * @param localRepositories The local repositories.
          * @return This session for chaining, never {@code null}.
-         * @see #newLocalRepositoryManager(LocalRepository...)
          */
         SessionBuilder withLocalRepositories(List<LocalRepository> localRepositories);
 
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultSessionBuilder.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultSessionBuilder.java
index 5052bbf42..4d2cc7fcb 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultSessionBuilder.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultSessionBuilder.java
@@ -429,9 +429,9 @@ public CloseableSession build() {
                 workspaceReader,
                 repositoryListener,
                 transferListener,
-                systemProperties,
-                userProperties,
-                configProperties,
+                copySafe(systemProperties, String.class),
+                copySafe(userProperties, String.class),
+                copySafe(configProperties, Object.class),
                 mirrorSelector,
                 proxySelector,
                 authenticationSelector,

From f823e9a9b62b86e9618c81a56a4b74cfc6f98cfc Mon Sep 17 00:00:00 2001
From: Tamas Cservenak <tamas@cservenak.net>
Date: Tue, 14 Nov 2023 20:00:22 +0100
Subject: [PATCH 5/5] Expose data and cache suppliers

This streamlines some logic.
---
 .../aether/RepositorySystemSession.java       | 20 +++++++++++-
 .../impl/session/DefaultSessionBuilder.java   | 31 +++++++++++++------
 2 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/RepositorySystemSession.java b/maven-resolver-api/src/main/java/org/eclipse/aether/RepositorySystemSession.java
index 189fd15d5..aff81d1f5 100644
--- a/maven-resolver-api/src/main/java/org/eclipse/aether/RepositorySystemSession.java
+++ b/maven-resolver-api/src/main/java/org/eclipse/aether/RepositorySystemSession.java
@@ -22,6 +22,7 @@
 import java.io.File;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Supplier;
 
 import org.eclipse.aether.artifact.ArtifactTypeRegistry;
 import org.eclipse.aether.collection.DependencyGraphTransformer;
@@ -97,7 +98,8 @@ interface CloseableSession extends RepositorySystemSession, Closeable {
      * <p>
      * Important: if you set a stateful member on builder (for example {@link SessionData} or {@link RepositoryCache}),
      * the builder will create session instances using same provided stateful members, that may lead to unexpected side
-     * effects. Solution for these cases is to not reuse builder instances.
+     * effects. Solution for these cases is to not reuse builder instances, or, keep reconfiguring it, or ultimately
+     * provide suppliers that create new instance per each call.
      *
      * @noimplement This interface is not intended to be implemented by clients.
      * @noextend This interface is not intended to be extended by clients.
@@ -388,6 +390,14 @@ interface SessionBuilder {
          */
         SessionBuilder setData(SessionData data);
 
+        /**
+         * Sets the custom session data supplier associated with this session.
+         *
+         * @param dataSupplier The session data supplier, may not be {@code null}.
+         * @return This session for chaining, never {@code null}.
+         */
+        SessionBuilder setSessionDataSupplier(Supplier<SessionData> dataSupplier);
+
         /**
          * Sets the cache the repository system may use to save data for future reuse during the session.
          *
@@ -396,6 +406,14 @@ interface SessionBuilder {
          */
         SessionBuilder setCache(RepositoryCache cache);
 
+        /**
+         * Sets the cache supplier for the repository system may use to save data for future reuse during the session.
+         *
+         * @param cacheSupplier The repository cache supplier, may not be {@code null}.
+         * @return This session for chaining, never {@code null}.
+         */
+        SessionBuilder setRepositoryCacheSupplier(Supplier<RepositoryCache> cacheSupplier);
+
         /**
          * Shortcut method to set up local repository manager directly onto builder. There must be at least one non-null
          * {@link File} passed in this method. In case multiple files, session builder will use chained local repository
diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultSessionBuilder.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultSessionBuilder.java
index 4d2cc7fcb..060863385 100644
--- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultSessionBuilder.java
+++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultSessionBuilder.java
@@ -67,6 +67,10 @@ public final class DefaultSessionBuilder implements SessionBuilder {
 
     private static final ArtifactTypeRegistry NULL_ARTIFACT_TYPE_REGISTRY = t -> null;
 
+    private static final Supplier<SessionData> DEFAULT_SESSION_DATA_SUPPLIER = DefaultSessionData::new;
+
+    private static final Supplier<RepositoryCache> DEFAULT_REPOSITORY_CACHE_SUPPLIER = () -> null;
+
     private final RepositorySystem repositorySystem;
 
     private final RepositorySystemLifecycle repositorySystemLifecycle;
@@ -123,9 +127,9 @@ public final class DefaultSessionBuilder implements SessionBuilder {
 
     private DependencyGraphTransformer dependencyGraphTransformer;
 
-    private SessionData data;
+    private Supplier<SessionData> sessionDataSupplier = DEFAULT_SESSION_DATA_SUPPLIER;
 
-    private RepositoryCache cache;
+    private Supplier<RepositoryCache> repositoryCacheSupplier = DEFAULT_REPOSITORY_CACHE_SUPPLIER;
 
     /**
      * Constructor for "top level" builders.
@@ -344,16 +348,25 @@ public DefaultSessionBuilder setDependencyGraphTransformer(DependencyGraphTransf
 
     @Override
     public DefaultSessionBuilder setData(SessionData data) {
-        this.data = data;
-        if (this.data == null) {
-            this.data = new DefaultSessionData();
-        }
+        return setSessionDataSupplier(() -> data);
+    }
+
+    @Override
+    public DefaultSessionBuilder setSessionDataSupplier(Supplier<SessionData> dataSupplier) {
+        requireNonNull(dataSupplier, "null dataSupplier");
+        this.sessionDataSupplier = dataSupplier;
         return this;
     }
 
     @Override
     public DefaultSessionBuilder setCache(RepositoryCache cache) {
-        this.cache = cache;
+        return setRepositoryCacheSupplier(() -> cache);
+    }
+
+    @Override
+    public DefaultSessionBuilder setRepositoryCacheSupplier(Supplier<RepositoryCache> cacheSupplier) {
+        requireNonNull(cacheSupplier, "null cacheSupplier");
+        this.repositoryCacheSupplier = cacheSupplier;
         return this;
     }
 
@@ -441,8 +454,8 @@ public CloseableSession build() {
                 dependencySelector,
                 versionFilter,
                 dependencyGraphTransformer,
-                data != null ? data : new DefaultSessionData(),
-                cache,
+                sessionDataSupplier.get(),
+                repositoryCacheSupplier.get(),
                 repositorySystem,
                 repositorySystemLifecycle);
     }