diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/AbstractForwardingRepositorySystemSession.java b/maven-resolver-api/src/main/java/org/eclipse/aether/AbstractForwardingRepositorySystemSession.java index 1fd95e305b..09670fdcc9 100644 --- a/maven-resolver-api/src/main/java/org/eclipse/aether/AbstractForwardingRepositorySystemSession.java +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/AbstractForwardingRepositorySystemSession.java @@ -21,6 +21,7 @@ import java.util.Map; import org.eclipse.aether.artifact.ArtifactTypeRegistry; +import org.eclipse.aether.collection.DependencyCollectionChecker; import org.eclipse.aether.collection.DependencyGraphTransformer; import org.eclipse.aether.collection.DependencyManager; import org.eclipse.aether.collection.DependencySelector; @@ -198,6 +199,11 @@ public ScopeManager getScopeManager() { return getSession().getScopeManager(); } + @Override + public DependencyCollectionChecker getDependencyCollectionChecker() { + return getSession().getDependencyCollectionChecker(); + } + @Override public SystemDependencyScope getSystemDependencyScope() { return getSession().getSystemDependencyScope(); diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositorySystemSession.java b/maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositorySystemSession.java index 5de1a5056b..b2cf0838cf 100644 --- a/maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositorySystemSession.java +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/DefaultRepositorySystemSession.java @@ -25,6 +25,7 @@ import org.eclipse.aether.artifact.ArtifactType; import org.eclipse.aether.artifact.ArtifactTypeRegistry; +import org.eclipse.aether.collection.DependencyCollectionChecker; import org.eclipse.aether.collection.DependencyGraphTransformer; import org.eclipse.aether.collection.DependencyManager; import org.eclipse.aether.collection.DependencySelector; @@ -128,6 +129,8 @@ public final class DefaultRepositorySystemSession implements RepositorySystemSes private ScopeManager scopeManager; + private DependencyCollectionChecker dependencyCollectionChecker; + private final Function onSessionEndedRegistrar; /** @@ -206,6 +209,7 @@ public DefaultRepositorySystemSession(RepositorySystemSession session) { setData(session.getData()); setCache(session.getCache()); setScopeManager(session.getScopeManager()); + setDependencyCollectionChecker(session.getDependencyCollectionChecker()); this.onSessionEndedRegistrar = session::addOnSessionEndedHandler; } @@ -832,6 +836,24 @@ public SystemDependencyScope getSystemDependencyScope() { } } + @Override + public DependencyCollectionChecker getDependencyCollectionChecker() { + return dependencyCollectionChecker; + } + + /** + * Sets the dependency collection checker, may be {@code null}. + * + * @param dependencyCollectionChecker The dependency collection checker, may be {@code null}. + * @return The session for chaining, never {@code null}. + * @since 2.0.19 + */ + public DefaultRepositorySystemSession setDependencyCollectionChecker( + DependencyCollectionChecker dependencyCollectionChecker) { + this.dependencyCollectionChecker = dependencyCollectionChecker; + return this; + } + /** * Registers onSessionEnded handler, if able to. * 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 0bf8dc56db..6c552bb01d 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 @@ -25,6 +25,7 @@ import java.util.function.Supplier; import org.eclipse.aether.artifact.ArtifactTypeRegistry; +import org.eclipse.aether.collection.DependencyCollectionChecker; import org.eclipse.aether.collection.DependencyGraphTransformer; import org.eclipse.aether.collection.DependencyManager; import org.eclipse.aether.collection.DependencySelector; @@ -405,6 +406,15 @@ interface SessionBuilder { */ SessionBuilder setScopeManager(ScopeManager scopeManager); + /** + * Sets the dependency collection checker, may be {@code null}. + * + * @param dependencyCollectionChecker The checker instance, may be {@code null}. + * @return The session for chaining, may be {@code null}. + * @since 2.0.19 + */ + SessionBuilder setDependencyCollectionChecker(DependencyCollectionChecker dependencyCollectionChecker); + /** * Adds on session ended handler to be immediately registered when this builder creates session. * @@ -782,6 +792,14 @@ interface SessionBuilder { */ SystemDependencyScope getSystemDependencyScope(); + /** + * Returns the dependency collector checker, may be {@code null}. + * + * @return The effective {@link DependencyCollectionChecker} instance, may be {@code null}. + * @since 2.0.19 + */ + DependencyCollectionChecker getDependencyCollectionChecker(); + /** * Registers a handler to execute when this session closed. *

diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/collection/DependencyCollectionChecker.java b/maven-resolver-api/src/main/java/org/eclipse/aether/collection/DependencyCollectionChecker.java new file mode 100644 index 0000000000..931ecde480 --- /dev/null +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/collection/DependencyCollectionChecker.java @@ -0,0 +1,58 @@ +/* + * 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.collection; + +import org.eclipse.aether.RepositorySystemSession; + +/** + * Dependency collector checker. It is able to check dependency collection result, deem it "satisfiable" or + * augment collection and re-execute it. + * + * @since 2.0.19 + */ +public interface DependencyCollectionChecker { + /** + * A default "no op" implementation. + */ + DependencyCollectionChecker NOOP = new DependencyCollectionChecker() {}; + + /** + * Config property for collector checker suppression. Presence of this key will suppress collection checking. + * This key is not meant for users, but to programmatically signal collection suppression. + */ + String COLLECTOR_CHECKER_SUPPRESSED = "aether.dependencyCollector.checker.suppressed"; + + /** + * Prepares for dependency collection. + */ + default RepositorySystemSession prepare(RepositorySystemSession session, CollectRequest request) { + return session; + } + + /** + * Performs checks on finished dependency collection. It should return {@code true} if the collection was deemed + * "satisfactory". If should return {@code false} only, if collection was not satisfactory, and checker + * was able to modify resolution parameters (to not repeat same work). In other cases (not satisfactory + * but no param change would help) it should throw {@link DependencyCollectionException}. + */ + default boolean isSatisfactory(RepositorySystemSession session, CollectRequest request, CollectResult result) + throws DependencyCollectionException { + return true; + } +} diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyCollectorDelegate.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyCollectorDelegate.java index 55b9cabfe1..a9d36745f3 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyCollectorDelegate.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyCollectorDelegate.java @@ -25,6 +25,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositoryException; @@ -33,6 +34,7 @@ import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.collection.CollectRequest; import org.eclipse.aether.collection.CollectResult; +import org.eclipse.aether.collection.DependencyCollectionChecker; import org.eclipse.aether.collection.DependencyCollectionException; import org.eclipse.aether.collection.DependencyGraphTransformer; import org.eclipse.aether.collection.DependencyTraverser; @@ -96,6 +98,19 @@ public abstract class DependencyCollectorDelegate implements DependencyCollector public static final int DEFAULT_MAX_CYCLES = 10; + /** + * The allowed runs of collection (and re-collection). By default, there must be at least 1 run, so values smaller + * than 1 are considered configuration errors and will fail dependency collection. + * + * @configurationSource {@link RepositorySystemSession#getConfigProperties()} + * @configurationType {@link java.lang.Integer} + * @configurationDefaultValue {@link #DEFAULT_MAX_RUNS} + * @since 2.0.19 + */ + public static final String CONFIG_PROP_MAX_RUNS = DefaultDependencyCollector.CONFIG_PROPS_PREFIX + "maxRuns"; + + public static final int DEFAULT_MAX_RUNS = 5; + protected final Logger logger = LoggerFactory.getLogger(getClass()); protected final RemoteRepositoryManager remoteRepositoryManager; @@ -121,153 +136,181 @@ protected DependencyCollectorDelegate( @SuppressWarnings("checkstyle:methodlength") @Override - public final CollectResult collectDependencies(RepositorySystemSession session, CollectRequest request) + public final CollectResult collectDependencies( + final RepositorySystemSession originalSession, final CollectRequest request) throws DependencyCollectionException { - requireNonNull(session, "session cannot be null"); + requireNonNull(originalSession, "session cannot be null"); requireNonNull(request, "request cannot be null"); - InternalScopeManager scopeManager = (InternalScopeManager) session.getScopeManager(); - session = setUpSession(session, request, scopeManager); - - RequestTrace trace = RequestTrace.newChild(request.getTrace(), request); - - CollectResult result = new CollectResult(request); - - DependencyTraverser depTraverser = session.getDependencyTraverser(); - VersionFilter verFilter = session.getVersionFilter(); - - Dependency root = request.getRoot(); - List repositories = request.getRepositories(); - List dependencies = request.getDependencies(); - List managedDependencies = request.getManagedDependencies(); + final InternalScopeManager scopeManager = (InternalScopeManager) originalSession.getScopeManager(); + final RepositorySystemSession setUpSession = setUpSession(originalSession, request, scopeManager); + final DependencyCollectionChecker dependencyCollectionChecker = + originalSession.getDependencyCollectionChecker() == null + ? DependencyCollectionChecker.NOOP + : originalSession.getDependencyCollectionChecker(); + + final RequestTrace trace = RequestTrace.newChild(request.getTrace(), request); + + final Map stats = new LinkedHashMap<>(); + final AtomicInteger runs = new AtomicInteger(0); + final int maxRuns = ConfigUtils.getInteger(originalSession, DEFAULT_MAX_RUNS, CONFIG_PROP_MAX_RUNS); + if (maxRuns < 1) { + throw new DependencyCollectionException( + new CollectResult(request), + "Invalid configuration: '" + CONFIG_PROP_MAX_RUNS + + "' configuration must be equal or grater than 1"); + } - Map stats = new LinkedHashMap<>(); - long time1 = System.nanoTime(); + CollectResult result = null; - DefaultDependencyNode node; - if (root != null) { - List versions; - VersionRangeResult rangeResult; - try { - VersionRangeRequest rangeRequest = new VersionRangeRequest( - root.getArtifact(), request.getRepositories(), request.getRequestContext()); - rangeRequest.setTrace(trace); - rangeResult = versionRangeResolver.resolveVersionRange(session, rangeRequest); - versions = filterVersions(root, rangeResult, verFilter, new DefaultVersionFilterContext(session)); - } catch (VersionRangeResolutionException e) { - result.addException(e); - throw new DependencyCollectionException(result, e.getMessage()); + boolean finished = false; + while (!finished) { + final long time1 = System.nanoTime(); + if (runs.incrementAndGet() > maxRuns) { + throw new DependencyCollectionException( + new CollectResult(request), + "Too many collection attempts (bug of used DependencyCollectionChecker?)"); } - Version version = versions.get(versions.size() - 1); - root = root.setArtifact(root.getArtifact().setVersion(version.toString())); + RepositorySystemSession session = dependencyCollectionChecker.prepare(setUpSession, request); + final DependencyTraverser depTraverser = session.getDependencyTraverser(); + final VersionFilter verFilter = session.getVersionFilter(); + + Dependency root = request.getRoot(); + List repositories = request.getRepositories(); + List dependencies = request.getDependencies(); + List managedDependencies = request.getManagedDependencies(); + + result = new CollectResult(request); + DefaultDependencyNode node; + if (root != null) { + List versions; + VersionRangeResult rangeResult; + try { + VersionRangeRequest rangeRequest = new VersionRangeRequest( + root.getArtifact(), request.getRepositories(), request.getRequestContext()); + rangeRequest.setTrace(trace); + rangeResult = versionRangeResolver.resolveVersionRange(session, rangeRequest); + versions = filterVersions(root, rangeResult, verFilter, new DefaultVersionFilterContext(session)); + } catch (VersionRangeResolutionException e) { + result.addException(e); + throw new DependencyCollectionException(result, e.getMessage()); + } - ArtifactDescriptorResult descriptorResult; - try { - ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest(); - descriptorRequest.setArtifact(root.getArtifact()); - descriptorRequest.setRepositories(request.getRepositories()); - descriptorRequest.setRequestContext(request.getRequestContext()); - descriptorRequest.setTrace(trace); - if (isLackingDescriptor(session, root.getArtifact())) { - descriptorResult = new ArtifactDescriptorResult(descriptorRequest); - } else { - descriptorResult = descriptorReader.readArtifactDescriptor(session, descriptorRequest); - for (ArtifactDecorator decorator : - Utils.getArtifactDecorators(session, artifactDecoratorFactories)) { - descriptorResult.setArtifact(decorator.decorateArtifact(descriptorResult)); + Version version = versions.get(versions.size() - 1); + root = root.setArtifact(root.getArtifact().setVersion(version.toString())); + + ArtifactDescriptorResult descriptorResult; + try { + ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest(); + descriptorRequest.setArtifact(root.getArtifact()); + descriptorRequest.setRepositories(request.getRepositories()); + descriptorRequest.setRequestContext(request.getRequestContext()); + descriptorRequest.setTrace(trace); + if (isLackingDescriptor(session, root.getArtifact())) { + descriptorResult = new ArtifactDescriptorResult(descriptorRequest); + } else { + descriptorResult = descriptorReader.readArtifactDescriptor(session, descriptorRequest); + for (ArtifactDecorator decorator : + Utils.getArtifactDecorators(session, artifactDecoratorFactories)) { + descriptorResult.setArtifact(decorator.decorateArtifact(descriptorResult)); + } } + } catch (ArtifactDescriptorException e) { + result.addException(e); + throw new DependencyCollectionException(result, e.getMessage()); } - } catch (ArtifactDescriptorException e) { - result.addException(e); - throw new DependencyCollectionException(result, e.getMessage()); - } - root = root.setArtifact(descriptorResult.getArtifact()); + root = root.setArtifact(descriptorResult.getArtifact()); - if (!session.isIgnoreArtifactDescriptorRepositories()) { - repositories = remoteRepositoryManager.aggregateRepositories( - session, repositories, descriptorResult.getRepositories(), true); + if (!session.isIgnoreArtifactDescriptorRepositories()) { + repositories = remoteRepositoryManager.aggregateRepositories( + session, repositories, descriptorResult.getRepositories(), true); + } + dependencies = mergeDeps(dependencies, descriptorResult.getDependencies()); + managedDependencies = mergeDeps(managedDependencies, descriptorResult.getManagedDependencies()); + + node = new DefaultDependencyNode(root); + node.setRequestContext(request.getRequestContext()); + node.setRelocations(descriptorResult.getRelocations()); + node.setVersionConstraint(rangeResult.getVersionConstraint()); + node.setVersion(version); + node.setAliases(descriptorResult.getAliases()); + node.setRepositories(request.getRepositories()); + } else { + node = new DefaultDependencyNode(request.getRootArtifact()); + node.setRequestContext(request.getRequestContext()); + node.setRepositories(request.getRepositories()); } - dependencies = mergeDeps(dependencies, descriptorResult.getDependencies()); - managedDependencies = mergeDeps(managedDependencies, descriptorResult.getManagedDependencies()); - - node = new DefaultDependencyNode(root); - node.setRequestContext(request.getRequestContext()); - node.setRelocations(descriptorResult.getRelocations()); - node.setVersionConstraint(rangeResult.getVersionConstraint()); - node.setVersion(version); - node.setAliases(descriptorResult.getAliases()); - node.setRepositories(request.getRepositories()); - } else { - node = new DefaultDependencyNode(request.getRootArtifact()); - node.setRequestContext(request.getRequestContext()); - node.setRepositories(request.getRepositories()); - } - result.setRoot(node); + result.setRoot(node); - boolean traverse = root == null || depTraverser == null || depTraverser.traverseDependency(root); - String errorPath = null; - if (traverse && !dependencies.isEmpty()) { - DataPool pool = new DataPool(session); + boolean traverse = root == null || depTraverser == null || depTraverser.traverseDependency(root); + String errorPath = null; + if (traverse && !dependencies.isEmpty()) { + DataPool pool = new DataPool(session); - DefaultDependencyCollectionContext context = new DefaultDependencyCollectionContext( - session, request.getRootArtifact(), root, managedDependencies); + DefaultDependencyCollectionContext context = new DefaultDependencyCollectionContext( + session, request.getRootArtifact(), root, managedDependencies); - DefaultVersionFilterContext versionContext = new DefaultVersionFilterContext(session); + DefaultVersionFilterContext versionContext = new DefaultVersionFilterContext(session); - Results results = new Results(result, session); + Results results = new Results(result, session); - doCollectDependencies( - session, - trace, - pool, - context, - versionContext, - request, - node, - repositories, - dependencies, - managedDependencies, - results); + doCollectDependencies( + session, + trace, + pool, + context, + versionContext, + request, + node, + repositories, + dependencies, + managedDependencies, + results); - errorPath = results.getErrorPath(); - } + errorPath = results.getErrorPath(); + } - long time2 = System.nanoTime(); + final long time2 = System.nanoTime(); + + DependencyGraphTransformer transformer = session.getDependencyGraphTransformer(); + if (transformer != null) { + try { + DefaultDependencyGraphTransformationContext context = + new DefaultDependencyGraphTransformationContext(session); + context.put(TransformationContextKeys.STATS, stats); + result.setRoot(transformer.transformGraph(node, context)); + } catch (RepositoryException e) { + result.addException(e); + } + } - DependencyGraphTransformer transformer = session.getDependencyGraphTransformer(); - if (transformer != null) { - try { - DefaultDependencyGraphTransformationContext context = - new DefaultDependencyGraphTransformationContext(session); - context.put(TransformationContextKeys.STATS, stats); - result.setRoot(transformer.transformGraph(node, context)); - } catch (RepositoryException e) { - result.addException(e); + if (errorPath != null) { + throw new DependencyCollectionException(result, "Failed to collect dependencies at " + errorPath); + } + if (!result.getExceptions().isEmpty()) { + throw new DependencyCollectionException(result); } - } - long time3 = System.nanoTime(); - if (logger.isDebugEnabled()) { + if (request.getResolutionScope() != null) { + result = scopeManager.postProcess(session, request.getResolutionScope(), result); + } + + long time3 = System.nanoTime(); stats.put(getClass().getSimpleName() + ".collectTime", time2 - time1); stats.put(getClass().getSimpleName() + ".transformTime", time3 - time2); - logger.debug("Dependency collection stats {}", stats); - } - if (errorPath != null) { - throw new DependencyCollectionException(result, "Failed to collect dependencies at " + errorPath); - } - if (!result.getExceptions().isEmpty()) { - throw new DependencyCollectionException(result); + finished = dependencyCollectionChecker.isSatisfactory(session, request, result); } - if (request.getResolutionScope() != null) { - return scopeManager.postProcess(session, request.getResolutionScope(), result); - } else { - return result; + stats.put(getClass().getSimpleName() + ".runs", runs.get()); + if (logger.isDebugEnabled()) { + logger.debug("Dependency collection stats {}", stats); } + + return result; } /** diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/scope/OptionalDependencySelector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/scope/OptionalDependencySelector.java index 7c0c324f07..aea51cf2a6 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/scope/OptionalDependencySelector.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/scope/OptionalDependencySelector.java @@ -18,11 +18,13 @@ */ package org.eclipse.aether.internal.impl.scope; +import java.util.Collection; import java.util.Objects; import org.eclipse.aether.collection.DependencyCollectionContext; import org.eclipse.aether.collection.DependencySelector; import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.util.artifact.ArtifactIdUtils; import static java.util.Objects.requireNonNull; @@ -35,6 +37,9 @@ * @see Dependency#isOptional() */ public final class OptionalDependencySelector implements DependencySelector { + public static final String IGNORED_KEYS = OptionalDependencySelector.class.getName() + ".ignored"; + public static final String UNSELECTED_KEYS = OptionalDependencySelector.class.getName() + ".unselected"; + /** * Excludes optional dependencies always (from root). */ @@ -56,29 +61,53 @@ public static OptionalDependencySelector from(int applyFrom) { if (applyFrom < 1) { throw new IllegalArgumentException("applyFrom must be non-zero and positive"); } - return new OptionalDependencySelector(Objects.hash(applyFrom), 0, applyFrom); + return new OptionalDependencySelector(Objects.hash(applyFrom), 0, applyFrom, null, null); } private final int seed; private final int depth; private final int applyFrom; + private final Collection ignoredKeys; + private final Collection unselectedKeys; - private OptionalDependencySelector(int seed, int depth, int applyFrom) { + private OptionalDependencySelector( + int seed, int depth, int applyFrom, Collection ignoredKeys, Collection unselectedKeys) { this.seed = seed; this.depth = depth; this.applyFrom = applyFrom; + this.ignoredKeys = ignoredKeys; // nullable + this.unselectedKeys = unselectedKeys; // nullable } @Override public boolean selectDependency(Dependency dependency) { requireNonNull(dependency, "dependency cannot be null"); - return depth < applyFrom || !dependency.isOptional(); + String key = null; + if (ignoredKeys != null || unselectedKeys != null) { + key = ArtifactIdUtils.toId(dependency.getArtifact()); + } + if (ignoredKeys != null) { + if (ignoredKeys.contains(key)) { + return true; + } + } + boolean result = depth < applyFrom || !dependency.isOptional(); + if (!result && unselectedKeys != null) { + unselectedKeys.add(key); + } + return result; } @Override + @SuppressWarnings("unchecked") public DependencySelector deriveChildSelector(DependencyCollectionContext context) { requireNonNull(context, "context cannot be null"); - return new OptionalDependencySelector(seed, depth + 1, applyFrom); + return new OptionalDependencySelector( + seed, + depth + 1, + applyFrom, + (Collection) context.getSession().getData().get(IGNORED_KEYS), + (Collection) context.getSession().getData().get(UNSELECTED_KEYS)); } @Override diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultCloseableSession.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultCloseableSession.java index ce9494c39e..d5b56c8948 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultCloseableSession.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/session/DefaultCloseableSession.java @@ -31,6 +31,7 @@ import org.eclipse.aether.RepositorySystemSession.CloseableSession; import org.eclipse.aether.SessionData; import org.eclipse.aether.artifact.ArtifactTypeRegistry; +import org.eclipse.aether.collection.DependencyCollectionChecker; import org.eclipse.aether.collection.DependencyGraphTransformer; import org.eclipse.aether.collection.DependencyManager; import org.eclipse.aether.collection.DependencySelector; @@ -113,6 +114,8 @@ public final class DefaultCloseableSession implements CloseableSession { private final ScopeManager scopeManager; + private final DependencyCollectionChecker dependencyCollectionChecker; + private final RepositorySystem repositorySystem; private final RepositorySystemLifecycle repositorySystemLifecycle; @@ -147,6 +150,7 @@ public DefaultCloseableSession( SessionData data, RepositoryCache cache, ScopeManager scopeManager, + DependencyCollectionChecker dependencyCollectionChecker, List onSessionEndedHandlers, RepositorySystem repositorySystem, RepositorySystemLifecycle repositorySystemLifecycle) { @@ -177,6 +181,7 @@ public DefaultCloseableSession( this.data = requireNonNull(data); this.cache = cache; this.scopeManager = scopeManager; + this.dependencyCollectionChecker = dependencyCollectionChecker; this.repositorySystem = requireNonNull(repositorySystem); this.repositorySystemLifecycle = requireNonNull(repositorySystemLifecycle); @@ -343,6 +348,11 @@ public ScopeManager getScopeManager() { return scopeManager; } + @Override + public DependencyCollectionChecker getDependencyCollectionChecker() { + return dependencyCollectionChecker; + } + @Override public SystemDependencyScope getSystemDependencyScope() { if (scopeManager != null) { 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 602f45b44f..bdf9fc3c9b 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 @@ -35,6 +35,7 @@ import org.eclipse.aether.RepositorySystemSession.SessionBuilder; import org.eclipse.aether.SessionData; import org.eclipse.aether.artifact.ArtifactTypeRegistry; +import org.eclipse.aether.collection.DependencyCollectionChecker; import org.eclipse.aether.collection.DependencyGraphTransformer; import org.eclipse.aether.collection.DependencyManager; import org.eclipse.aether.collection.DependencySelector; @@ -133,6 +134,8 @@ public final class DefaultSessionBuilder implements SessionBuilder { private ScopeManager scopeManager; + private DependencyCollectionChecker dependencyCollectionChecker; + private final ArrayList onSessionCloseHandlers = new ArrayList<>(); /** @@ -363,6 +366,12 @@ public DefaultSessionBuilder setScopeManager(ScopeManager scopeManager) { return this; } + @Override + public SessionBuilder setDependencyCollectionChecker(DependencyCollectionChecker dependencyCollectionChecker) { + this.dependencyCollectionChecker = dependencyCollectionChecker; + return null; + } + @Override public SessionBuilder addOnSessionEndedHandler(Runnable handler) { requireNonNull(handler, "null handler"); @@ -485,6 +494,7 @@ public CloseableSession build() { sessionDataSupplier.get(), repositoryCacheSupplier.get(), scopeManager, + dependencyCollectionChecker, onSessionCloseHandlers, repositorySystem, repositorySystemLifecycle);