001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.eclipse.aether.internal.impl.collect.bf; 020 021import javax.inject.Inject; 022import javax.inject.Named; 023import javax.inject.Singleton; 024 025import java.io.Closeable; 026import java.util.ArrayDeque; 027import java.util.ArrayList; 028import java.util.Collections; 029import java.util.LinkedHashMap; 030import java.util.List; 031import java.util.Map; 032import java.util.Optional; 033import java.util.Queue; 034import java.util.Set; 035import java.util.concurrent.Callable; 036import java.util.concurrent.ConcurrentHashMap; 037import java.util.concurrent.ExecutionException; 038import java.util.concurrent.ExecutorService; 039import java.util.concurrent.Future; 040import java.util.concurrent.TimeUnit; 041import java.util.concurrent.TimeoutException; 042import java.util.concurrent.atomic.AtomicReference; 043import java.util.stream.Collectors; 044import java.util.stream.Stream; 045 046import org.eclipse.aether.RepositorySystemSession; 047import org.eclipse.aether.RequestTrace; 048import org.eclipse.aether.artifact.Artifact; 049import org.eclipse.aether.artifact.ArtifactType; 050import org.eclipse.aether.artifact.DefaultArtifact; 051import org.eclipse.aether.collection.CollectRequest; 052import org.eclipse.aether.collection.DependencyCollectionException; 053import org.eclipse.aether.collection.DependencyManager; 054import org.eclipse.aether.collection.DependencySelector; 055import org.eclipse.aether.collection.DependencyTraverser; 056import org.eclipse.aether.collection.VersionFilter; 057import org.eclipse.aether.graph.DefaultDependencyNode; 058import org.eclipse.aether.graph.Dependency; 059import org.eclipse.aether.graph.DependencyNode; 060import org.eclipse.aether.impl.ArtifactDescriptorReader; 061import org.eclipse.aether.impl.RemoteRepositoryManager; 062import org.eclipse.aether.impl.VersionRangeResolver; 063import org.eclipse.aether.internal.impl.collect.DataPool; 064import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollectionContext; 065import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollector; 066import org.eclipse.aether.internal.impl.collect.DefaultVersionFilterContext; 067import org.eclipse.aether.internal.impl.collect.DependencyCollectorDelegate; 068import org.eclipse.aether.internal.impl.collect.PremanagedDependency; 069import org.eclipse.aether.repository.RemoteRepository; 070import org.eclipse.aether.resolution.ArtifactDescriptorException; 071import org.eclipse.aether.resolution.ArtifactDescriptorRequest; 072import org.eclipse.aether.resolution.ArtifactDescriptorResult; 073import org.eclipse.aether.resolution.VersionRangeRequest; 074import org.eclipse.aether.resolution.VersionRangeResult; 075import org.eclipse.aether.util.ConfigUtils; 076import org.eclipse.aether.util.artifact.ArtifactIdUtils; 077import org.eclipse.aether.util.concurrency.ExecutorUtils; 078import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; 079import org.eclipse.aether.version.Version; 080 081import static org.eclipse.aether.internal.impl.collect.DefaultDependencyCycle.find; 082 083/** 084 * Breadth-first {@link org.eclipse.aether.impl.DependencyCollector} 085 * 086 * @since 1.8.0 087 */ 088@Singleton 089@Named(BfDependencyCollector.NAME) 090public class BfDependencyCollector extends DependencyCollectorDelegate { 091 public static final String NAME = "bf"; 092 093 private static final String CONFIG_PROPS_PREFIX = DefaultDependencyCollector.CONFIG_PROPS_PREFIX + NAME + "."; 094 095 /** 096 * The key in the repository session's {@link RepositorySystemSession#getConfigProperties() 097 * configuration properties} used to store a {@link Boolean} flag controlling the resolver's skip mode. 098 * 099 * @since 1.8.0 100 * @configurationSource {@link RepositorySystemSession#getConfigProperties()} 101 * @configurationType {@link java.lang.Boolean} 102 * @configurationDefaultValue {@link #DEFAULT_SKIPPER} 103 */ 104 public static final String CONFIG_PROP_SKIPPER = CONFIG_PROPS_PREFIX + "skipper"; 105 106 /** 107 * The default value for {@link #CONFIG_PROP_SKIPPER}, {@code true}. 108 * 109 * @since 1.8.0 110 */ 111 public static final boolean DEFAULT_SKIPPER = true; 112 113 /** 114 * The count of threads to be used when collecting POMs in parallel. 115 * 116 * @since 1.9.0 117 * @configurationSource {@link RepositorySystemSession#getConfigProperties()} 118 * @configurationType {@link java.lang.Integer} 119 * @configurationDefaultValue {@link #DEFAULT_THREADS} 120 */ 121 public static final String CONFIG_PROP_THREADS = CONFIG_PROPS_PREFIX + "threads"; 122 123 /** 124 * The default value for {@link #CONFIG_PROP_THREADS}, default value 5. 125 * 126 * @since 1.9.0 127 */ 128 public static final int DEFAULT_THREADS = 5; 129 130 @Inject 131 public BfDependencyCollector( 132 RemoteRepositoryManager remoteRepositoryManager, 133 ArtifactDescriptorReader artifactDescriptorReader, 134 VersionRangeResolver versionRangeResolver) { 135 super(remoteRepositoryManager, artifactDescriptorReader, versionRangeResolver); 136 } 137 138 @SuppressWarnings("checkstyle:parameternumber") 139 @Override 140 protected void doCollectDependencies( 141 RepositorySystemSession session, 142 RequestTrace trace, 143 DataPool pool, 144 DefaultDependencyCollectionContext context, 145 DefaultVersionFilterContext versionContext, 146 CollectRequest request, 147 DependencyNode node, 148 List<RemoteRepository> repositories, 149 List<Dependency> dependencies, 150 List<Dependency> managedDependencies, 151 Results results) 152 throws DependencyCollectionException { 153 boolean useSkip = ConfigUtils.getBoolean(session, DEFAULT_SKIPPER, CONFIG_PROP_SKIPPER); 154 int nThreads = ExecutorUtils.threadCount(session, DEFAULT_THREADS, CONFIG_PROP_THREADS); 155 logger.debug("Using thread pool with {} threads to resolve descriptors.", nThreads); 156 157 if (useSkip) { 158 logger.debug("Collector skip mode enabled"); 159 } 160 161 try (DependencyResolutionSkipper skipper = useSkip 162 ? DependencyResolutionSkipper.defaultSkipper() 163 : DependencyResolutionSkipper.neverSkipper(); 164 ParallelDescriptorResolver parallelDescriptorResolver = new ParallelDescriptorResolver(nThreads)) { 165 Args args = new Args(session, pool, context, versionContext, request, skipper, parallelDescriptorResolver); 166 167 DependencySelector rootDepSelector = session.getDependencySelector() != null 168 ? session.getDependencySelector().deriveChildSelector(context) 169 : null; 170 DependencyManager rootDepManager = session.getDependencyManager() != null 171 ? session.getDependencyManager().deriveChildManager(context) 172 : null; 173 DependencyTraverser rootDepTraverser = session.getDependencyTraverser() != null 174 ? session.getDependencyTraverser().deriveChildTraverser(context) 175 : null; 176 VersionFilter rootVerFilter = session.getVersionFilter() != null 177 ? session.getVersionFilter().deriveChildFilter(context) 178 : null; 179 180 List<DependencyNode> parents = Collections.singletonList(node); 181 for (Dependency dependency : dependencies) { 182 RequestTrace childTrace = 183 collectStepTrace(trace, args.request.getRequestContext(), parents, dependency); 184 DependencyProcessingContext processingContext = new DependencyProcessingContext( 185 rootDepSelector, 186 rootDepManager, 187 rootDepTraverser, 188 rootVerFilter, 189 childTrace, 190 repositories, 191 managedDependencies, 192 parents, 193 dependency, 194 PremanagedDependency.create(rootDepManager, dependency, false, args.premanagedState)); 195 if (!filter(processingContext)) { 196 processingContext.withDependency(processingContext.premanagedDependency.getManagedDependency()); 197 resolveArtifactDescriptorAsync(args, processingContext, results); 198 args.dependencyProcessingQueue.add(processingContext); 199 } 200 } 201 202 while (!args.dependencyProcessingQueue.isEmpty()) { 203 processDependency( 204 args, results, args.dependencyProcessingQueue.remove(), Collections.emptyList(), false); 205 } 206 207 if (args.interruptedException.get() != null) { 208 throw new DependencyCollectionException( 209 results.getResult(), "Collection interrupted", args.interruptedException.get()); 210 } 211 } 212 } 213 214 @SuppressWarnings("checkstyle:parameternumber") 215 private void processDependency( 216 Args args, 217 Results results, 218 DependencyProcessingContext context, 219 List<Artifact> relocations, 220 boolean disableVersionManagement) { 221 if (Thread.interrupted()) { 222 args.interruptedException.set(new InterruptedException()); 223 } 224 if (args.interruptedException.get() != null) { 225 return; 226 } 227 Dependency dependency = context.dependency; 228 PremanagedDependency preManaged = context.premanagedDependency; 229 230 boolean noDescriptor = isLackingDescriptor(args.session, dependency.getArtifact()); 231 boolean traverse = 232 !noDescriptor && (context.depTraverser == null || context.depTraverser.traverseDependency(dependency)); 233 234 Future<DescriptorResolutionResult> resolutionResultFuture = args.resolver.find(dependency.getArtifact()); 235 DescriptorResolutionResult resolutionResult; 236 VersionRangeResult rangeResult; 237 try { 238 resolutionResult = resolutionResultFuture.get(); 239 rangeResult = resolutionResult.rangeResult; 240 } catch (Exception e) { 241 results.addException(dependency, e, context.parents); 242 return; 243 } 244 245 Set<Version> versions = resolutionResult.descriptors.keySet(); 246 for (Version version : versions) { 247 Artifact originalArtifact = dependency.getArtifact().setVersion(version.toString()); 248 Dependency d = dependency.setArtifact(originalArtifact); 249 250 final ArtifactDescriptorResult descriptorResult = resolutionResult.descriptors.get(version); 251 if (descriptorResult != null) { 252 d = d.setArtifact(descriptorResult.getArtifact()); 253 254 int cycleEntry = find(context.parents, d.getArtifact()); 255 if (cycleEntry >= 0) { 256 results.addCycle(context.parents, cycleEntry, d); 257 DependencyNode cycleNode = context.parents.get(cycleEntry); 258 if (cycleNode.getDependency() != null) { 259 DefaultDependencyNode child = createDependencyNode( 260 relocations, preManaged, rangeResult, version, d, descriptorResult, cycleNode); 261 context.getParent().getChildren().add(child); 262 continue; 263 } 264 } 265 266 if (!descriptorResult.getRelocations().isEmpty()) { 267 boolean disableVersionManagementSubsequently = 268 originalArtifact.getGroupId().equals(d.getArtifact().getGroupId()) 269 && originalArtifact 270 .getArtifactId() 271 .equals(d.getArtifact().getArtifactId()); 272 273 PremanagedDependency premanagedDependency = PremanagedDependency.create( 274 context.depManager, d, disableVersionManagementSubsequently, args.premanagedState); 275 DependencyProcessingContext relocatedContext = new DependencyProcessingContext( 276 context.depSelector, 277 context.depManager, 278 context.depTraverser, 279 context.verFilter, 280 context.trace, 281 context.repositories, 282 descriptorResult.getManagedDependencies(), 283 context.parents, 284 d, 285 premanagedDependency); 286 287 if (!filter(relocatedContext)) { 288 relocatedContext.withDependency(premanagedDependency.getManagedDependency()); 289 resolveArtifactDescriptorAsync(args, relocatedContext, results); 290 processDependency( 291 args, 292 results, 293 relocatedContext, 294 descriptorResult.getRelocations(), 295 disableVersionManagementSubsequently); 296 } 297 298 return; 299 } else { 300 d = args.pool.intern(d.setArtifact(args.pool.intern(d.getArtifact()))); 301 302 List<RemoteRepository> repos = 303 getRemoteRepositories(rangeResult.getRepository(version), context.repositories); 304 305 DefaultDependencyNode child = createDependencyNode( 306 relocations, 307 preManaged, 308 rangeResult, 309 version, 310 d, 311 descriptorResult.getAliases(), 312 repos, 313 args.request.getRequestContext()); 314 315 context.getParent().getChildren().add(child); 316 317 boolean recurse = 318 traverse && !descriptorResult.getDependencies().isEmpty(); 319 DependencyProcessingContext parentContext = context.withDependency(d); 320 if (recurse) { 321 doRecurse(args, parentContext, descriptorResult, child, results, disableVersionManagement); 322 } else if (!args.skipper.skipResolution(child, parentContext.parents)) { 323 List<DependencyNode> parents = new ArrayList<>(parentContext.parents.size() + 1); 324 parents.addAll(parentContext.parents); 325 parents.add(child); 326 args.skipper.cache(child, parents); 327 } 328 } 329 } else { 330 List<RemoteRepository> repos = 331 getRemoteRepositories(rangeResult.getRepository(version), context.repositories); 332 DefaultDependencyNode child = createDependencyNode( 333 relocations, 334 preManaged, 335 rangeResult, 336 version, 337 d, 338 null, 339 repos, 340 args.request.getRequestContext()); 341 context.getParent().getChildren().add(child); 342 } 343 } 344 } 345 346 @SuppressWarnings("checkstyle:parameternumber") 347 private void doRecurse( 348 Args args, 349 DependencyProcessingContext parentContext, 350 ArtifactDescriptorResult descriptorResult, 351 DefaultDependencyNode child, 352 Results results, 353 boolean disableVersionManagement) { 354 DefaultDependencyCollectionContext context = args.collectionContext; 355 context.set(parentContext.dependency, descriptorResult.getManagedDependencies()); 356 357 DependencySelector childSelector = 358 parentContext.depSelector != null ? parentContext.depSelector.deriveChildSelector(context) : null; 359 DependencyManager childManager = 360 parentContext.depManager != null ? parentContext.depManager.deriveChildManager(context) : null; 361 DependencyTraverser childTraverser = 362 parentContext.depTraverser != null ? parentContext.depTraverser.deriveChildTraverser(context) : null; 363 VersionFilter childFilter = 364 parentContext.verFilter != null ? parentContext.verFilter.deriveChildFilter(context) : null; 365 366 final List<RemoteRepository> childRepos = args.ignoreRepos 367 ? parentContext.repositories 368 : remoteRepositoryManager.aggregateRepositories( 369 args.session, parentContext.repositories, descriptorResult.getRepositories(), true); 370 371 Object key = args.pool.toKey( 372 parentContext.dependency.getArtifact(), 373 childRepos, 374 childSelector, 375 childManager, 376 childTraverser, 377 childFilter); 378 379 List<DependencyNode> children = args.pool.getChildren(key); 380 if (children == null) { 381 boolean skipResolution = args.skipper.skipResolution(child, parentContext.parents); 382 if (!skipResolution) { 383 List<DependencyNode> parents = new ArrayList<>(parentContext.parents.size() + 1); 384 parents.addAll(parentContext.parents); 385 parents.add(child); 386 for (Dependency dependency : descriptorResult.getDependencies()) { 387 RequestTrace childTrace = collectStepTrace( 388 parentContext.trace, args.request.getRequestContext(), parents, dependency); 389 PremanagedDependency premanagedDependency = PremanagedDependency.create( 390 childManager, dependency, disableVersionManagement, args.premanagedState); 391 DependencyProcessingContext processingContext = new DependencyProcessingContext( 392 childSelector, 393 childManager, 394 childTraverser, 395 childFilter, 396 childTrace, 397 childRepos, 398 descriptorResult.getManagedDependencies(), 399 parents, 400 dependency, 401 premanagedDependency); 402 if (!filter(processingContext)) { 403 // resolve descriptors ahead for managed dependency 404 processingContext.withDependency(processingContext.premanagedDependency.getManagedDependency()); 405 resolveArtifactDescriptorAsync(args, processingContext, results); 406 args.dependencyProcessingQueue.add(processingContext); 407 } 408 } 409 args.pool.putChildren(key, child.getChildren()); 410 args.skipper.cache(child, parents); 411 } 412 } else { 413 child.setChildren(children); 414 } 415 } 416 417 private boolean filter(DependencyProcessingContext context) { 418 return context.depSelector != null && !context.depSelector.selectDependency(context.dependency); 419 } 420 421 private void resolveArtifactDescriptorAsync(Args args, DependencyProcessingContext context, Results results) { 422 Dependency dependency = context.dependency; 423 args.resolver.resolveDescriptors(dependency.getArtifact(), () -> { 424 VersionRangeRequest rangeRequest = createVersionRangeRequest( 425 args.request.getRequestContext(), context.trace, context.repositories, dependency); 426 VersionRangeResult rangeResult = cachedResolveRangeResult(rangeRequest, args.pool, args.session); 427 List<? extends Version> versions = 428 filterVersions(dependency, rangeResult, context.verFilter, args.versionContext); 429 430 // resolve newer version first to maximize benefits of skipper 431 Collections.reverse(versions); 432 433 Map<Version, ArtifactDescriptorResult> descriptors = new ConcurrentHashMap<>(versions.size()); 434 Stream<? extends Version> stream = versions.size() > 1 ? versions.parallelStream() : versions.stream(); 435 stream.forEach(version -> Optional.ofNullable( 436 resolveDescriptorForVersion(args, context, results, dependency, version)) 437 .ifPresent(r -> descriptors.put(version, r))); 438 439 DescriptorResolutionResult resolutionResult = 440 new DescriptorResolutionResult(dependency.getArtifact(), rangeResult); 441 // keep original sequence 442 versions.forEach(version -> resolutionResult.descriptors.put(version, descriptors.get(version))); 443 // populate for versions in version range 444 resolutionResult.flatten().forEach(dr -> args.resolver.cacheVersionRangeDescriptor(dr.artifact, dr)); 445 446 return resolutionResult; 447 }); 448 } 449 450 private ArtifactDescriptorResult resolveDescriptorForVersion( 451 Args args, DependencyProcessingContext context, Results results, Dependency dependency, Version version) { 452 Artifact original = dependency.getArtifact(); 453 Artifact newArtifact = new DefaultArtifact( 454 original.getGroupId(), 455 original.getArtifactId(), 456 original.getClassifier(), 457 original.getExtension(), 458 version.toString(), 459 original.getProperties(), 460 (ArtifactType) null); 461 Dependency newDependency = 462 new Dependency(newArtifact, dependency.getScope(), dependency.isOptional(), dependency.getExclusions()); 463 DependencyProcessingContext newContext = context.copy(); 464 465 ArtifactDescriptorRequest descriptorRequest = createArtifactDescriptorRequest( 466 args.request.getRequestContext(), context.trace, newContext.repositories, newDependency); 467 return isLackingDescriptor(args.session, newArtifact) 468 ? new ArtifactDescriptorResult(descriptorRequest) 469 : resolveCachedArtifactDescriptor( 470 args.pool, descriptorRequest, args.session, newContext.withDependency(newDependency), results); 471 } 472 473 private ArtifactDescriptorResult resolveCachedArtifactDescriptor( 474 DataPool pool, 475 ArtifactDescriptorRequest descriptorRequest, 476 RepositorySystemSession session, 477 DependencyProcessingContext context, 478 Results results) { 479 Object key = pool.toKey(descriptorRequest); 480 ArtifactDescriptorResult descriptorResult = pool.getDescriptor(key, descriptorRequest); 481 if (descriptorResult == null) { 482 try { 483 descriptorResult = descriptorReader.readArtifactDescriptor(session, descriptorRequest); 484 pool.putDescriptor(key, descriptorResult); 485 } catch (ArtifactDescriptorException e) { 486 results.addException(context.dependency, e, context.parents); 487 pool.putDescriptor(key, e); 488 return null; 489 } 490 491 } else if (descriptorResult == DataPool.NO_DESCRIPTOR) { 492 return null; 493 } 494 495 return descriptorResult; 496 } 497 498 static class ParallelDescriptorResolver implements Closeable { 499 private final ExecutorService executorService; 500 501 /** 502 * Artifact ID -> Future of DescriptorResolutionResult 503 */ 504 private final Map<String, Future<DescriptorResolutionResult>> results = new ConcurrentHashMap<>(256); 505 506 ParallelDescriptorResolver(int threads) { 507 this.executorService = ExecutorUtils.threadPool(threads, getClass().getSimpleName() + "-"); 508 } 509 510 void resolveDescriptors(Artifact artifact, Callable<DescriptorResolutionResult> callable) { 511 results.computeIfAbsent(ArtifactIdUtils.toId(artifact), key -> this.executorService.submit(callable)); 512 } 513 514 void cacheVersionRangeDescriptor(Artifact artifact, DescriptorResolutionResult resolutionResult) { 515 results.computeIfAbsent(ArtifactIdUtils.toId(artifact), key -> new DoneFuture<>(resolutionResult)); 516 } 517 518 Future<DescriptorResolutionResult> find(Artifact artifact) { 519 return results.get(ArtifactIdUtils.toId(artifact)); 520 } 521 522 @Override 523 public void close() { 524 executorService.shutdown(); 525 } 526 } 527 528 static class DoneFuture<V> implements Future<V> { 529 private final V v; 530 531 DoneFuture(V v) { 532 this.v = v; 533 } 534 535 @Override 536 public boolean cancel(boolean mayInterruptIfRunning) { 537 return false; 538 } 539 540 @Override 541 public boolean isCancelled() { 542 return false; 543 } 544 545 @Override 546 public boolean isDone() { 547 return true; 548 } 549 550 @Override 551 public V get() throws InterruptedException, ExecutionException { 552 return v; 553 } 554 555 @Override 556 public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { 557 return v; 558 } 559 } 560 561 static class DescriptorResolutionResult { 562 Artifact artifact; 563 564 VersionRangeResult rangeResult; 565 566 Map<Version, ArtifactDescriptorResult> descriptors; 567 568 DescriptorResolutionResult(Artifact artifact, VersionRangeResult rangeResult) { 569 this.artifact = artifact; 570 this.rangeResult = rangeResult; 571 this.descriptors = new LinkedHashMap<>(rangeResult.getVersions().size()); 572 } 573 574 DescriptorResolutionResult( 575 VersionRangeResult rangeResult, Version version, ArtifactDescriptorResult descriptor) { 576 // NOTE: In case of A1 -> A2 relocation this happens: 577 // ArtifactDescriptorResult read by ArtifactDescriptorResultReader for A1 578 // will return instance that will have artifact = A2 (as RelocatedArtifact). 579 // So to properly "key" this instance, we need to use "originally requested" A1 instead! 580 // In short: 581 // ArtifactDescriptorRequest.artifact != ArtifactDescriptorResult.artifact WHEN relocation in play 582 // otherwise (no relocation), they are EQUAL. 583 this(descriptor.getRequest().getArtifact(), rangeResult); 584 this.descriptors.put(version, descriptor); 585 } 586 587 List<DescriptorResolutionResult> flatten() { 588 if (descriptors.size() > 1) { 589 return descriptors.entrySet().stream() 590 .map(e -> new DescriptorResolutionResult(rangeResult, e.getKey(), e.getValue())) 591 .collect(Collectors.toList()); 592 } else { 593 return Collections.emptyList(); 594 } 595 } 596 } 597 598 static class Args { 599 600 final RepositorySystemSession session; 601 602 final boolean ignoreRepos; 603 604 final boolean premanagedState; 605 606 final DataPool pool; 607 608 final Queue<DependencyProcessingContext> dependencyProcessingQueue = new ArrayDeque<>(128); 609 610 final DefaultDependencyCollectionContext collectionContext; 611 612 final DefaultVersionFilterContext versionContext; 613 614 final CollectRequest request; 615 616 final DependencyResolutionSkipper skipper; 617 618 final ParallelDescriptorResolver resolver; 619 620 final AtomicReference<InterruptedException> interruptedException; 621 622 Args( 623 RepositorySystemSession session, 624 DataPool pool, 625 DefaultDependencyCollectionContext collectionContext, 626 DefaultVersionFilterContext versionContext, 627 CollectRequest request, 628 DependencyResolutionSkipper skipper, 629 ParallelDescriptorResolver resolver) { 630 this.session = session; 631 this.request = request; 632 this.ignoreRepos = session.isIgnoreArtifactDescriptorRepositories(); 633 this.premanagedState = ConfigUtils.getBoolean(session, false, DependencyManagerUtils.CONFIG_PROP_VERBOSE); 634 this.pool = pool; 635 this.collectionContext = collectionContext; 636 this.versionContext = versionContext; 637 this.skipper = skipper; 638 this.resolver = resolver; 639 this.interruptedException = new AtomicReference<>(null); 640 } 641 } 642}