View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.internal.impl.collect.bf;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.io.Closeable;
26  import java.util.ArrayDeque;
27  import java.util.ArrayList;
28  import java.util.Arrays;
29  import java.util.Collections;
30  import java.util.LinkedHashMap;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.Optional;
34  import java.util.Queue;
35  import java.util.Set;
36  import java.util.concurrent.Callable;
37  import java.util.concurrent.CompletableFuture;
38  import java.util.concurrent.ConcurrentHashMap;
39  import java.util.concurrent.Future;
40  import java.util.concurrent.atomic.AtomicReference;
41  import java.util.function.Supplier;
42  import java.util.stream.Collectors;
43  import java.util.stream.Stream;
44  
45  import org.eclipse.aether.RepositorySystemSession;
46  import org.eclipse.aether.RequestTrace;
47  import org.eclipse.aether.artifact.Artifact;
48  import org.eclipse.aether.collection.CollectRequest;
49  import org.eclipse.aether.collection.DependencyCollectionException;
50  import org.eclipse.aether.collection.DependencyManager;
51  import org.eclipse.aether.collection.DependencySelector;
52  import org.eclipse.aether.collection.DependencyTraverser;
53  import org.eclipse.aether.collection.VersionFilter;
54  import org.eclipse.aether.graph.DefaultDependencyNode;
55  import org.eclipse.aether.graph.Dependency;
56  import org.eclipse.aether.graph.DependencyNode;
57  import org.eclipse.aether.impl.ArtifactDescriptorReader;
58  import org.eclipse.aether.impl.RemoteRepositoryManager;
59  import org.eclipse.aether.impl.VersionRangeResolver;
60  import org.eclipse.aether.internal.impl.collect.DataPool;
61  import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollectionContext;
62  import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollector;
63  import org.eclipse.aether.internal.impl.collect.DefaultVersionFilterContext;
64  import org.eclipse.aether.internal.impl.collect.DependencyCollectorDelegate;
65  import org.eclipse.aether.internal.impl.collect.PremanagedDependency;
66  import org.eclipse.aether.repository.RemoteRepository;
67  import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
68  import org.eclipse.aether.resolution.ArtifactDescriptorResult;
69  import org.eclipse.aether.resolution.VersionRangeRequest;
70  import org.eclipse.aether.resolution.VersionRangeResult;
71  import org.eclipse.aether.spi.artifact.decorator.ArtifactDecoratorFactory;
72  import org.eclipse.aether.util.ConfigUtils;
73  import org.eclipse.aether.util.artifact.ArtifactIdUtils;
74  import org.eclipse.aether.util.concurrency.SmartExecutor;
75  import org.eclipse.aether.util.concurrency.SmartExecutorUtils;
76  import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
77  import org.eclipse.aether.version.Version;
78  
79  import static org.eclipse.aether.internal.impl.collect.DefaultDependencyCycle.find;
80  
81  /**
82   * Breadth-first {@link org.eclipse.aether.impl.DependencyCollector}
83   *
84   * @since 1.8.0
85   */
86  @Singleton
87  @Named(BfDependencyCollector.NAME)
88  public class BfDependencyCollector extends DependencyCollectorDelegate {
89      public static final String NAME = "bf";
90  
91      private static final String CONFIG_PROPS_PREFIX = DefaultDependencyCollector.CONFIG_PROPS_PREFIX + NAME + ".";
92  
93      /**
94       * The key in the repository session's {@link RepositorySystemSession#getConfigProperties()
95       * configuration properties} used to store a {@link String} flag controlling the resolver's skip mode.
96       * Supported modes are "versionless" (default), "versioned" and "false" to not use skipper. The first two modes
97       * are defining "function" how to map artifact coordinates to (String) key while deciding "skip" logic.
98       * The "versionless" uses {@code G:A:C:E} coordinate elements only (without version), while "versioned" uses
99       * all {@code G:A:C:E:V} artifact coordinates.
100      *
101      * @since 1.8.0
102      * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
103      * @configurationType {@link java.lang.String}
104      * @configurationDefaultValue {@link #DEFAULT_SKIPPER}
105      */
106     public static final String CONFIG_PROP_SKIPPER = CONFIG_PROPS_PREFIX + "skipper";
107 
108     public static final String NONE_SKIPPER = "false";
109     public static final String VERSIONLESS_SKIPPER = "versionless";
110     public static final String VERSIONED_SKIPPER = "versioned";
111 
112     /**
113      * The default value for {@link #CONFIG_PROP_SKIPPER}, {@code true}.
114      *
115      * @since 1.8.0
116      */
117     public static final String DEFAULT_SKIPPER = VERSIONLESS_SKIPPER;
118 
119     /**
120      * The count of threads to be used when collecting POMs in parallel.
121      *
122      * @since 1.9.0
123      * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
124      * @configurationType {@link java.lang.Integer}
125      * @configurationDefaultValue {@link #DEFAULT_THREADS}
126      */
127     public static final String CONFIG_PROP_THREADS = CONFIG_PROPS_PREFIX + "threads";
128 
129     /**
130      * The default value for {@link #CONFIG_PROP_THREADS}, default value 5.
131      *
132      * @since 1.9.0
133      */
134     public static final int DEFAULT_THREADS = 5;
135 
136     @Inject
137     public BfDependencyCollector(
138             RemoteRepositoryManager remoteRepositoryManager,
139             ArtifactDescriptorReader artifactDescriptorReader,
140             VersionRangeResolver versionRangeResolver,
141             Map<String, ArtifactDecoratorFactory> artifactDecoratorFactories) {
142         super(remoteRepositoryManager, artifactDescriptorReader, versionRangeResolver, artifactDecoratorFactories);
143     }
144 
145     @SuppressWarnings("checkstyle:parameternumber")
146     @Override
147     protected void doCollectDependencies(
148             RepositorySystemSession session,
149             RequestTrace trace,
150             DataPool pool,
151             DefaultDependencyCollectionContext context,
152             DefaultVersionFilterContext versionContext,
153             CollectRequest request,
154             DependencyNode node,
155             List<RemoteRepository> repositories,
156             List<Dependency> dependencies,
157             List<Dependency> managedDependencies,
158             Results results)
159             throws DependencyCollectionException {
160         String skipperMode = ConfigUtils.getString(session, DEFAULT_SKIPPER, CONFIG_PROP_SKIPPER);
161         Supplier<DependencyResolutionSkipper> skipperSupplier;
162         if (NONE_SKIPPER.equals(skipperMode)) {
163             logger.debug("Collector skip mode disabled");
164             skipperSupplier = DependencyResolutionSkipper::neverSkipper;
165         } else if (VERSIONLESS_SKIPPER.equals(skipperMode)) {
166             logger.debug("Collector skip mode enabled: {} (key function GACE)", skipperMode);
167             skipperSupplier = DependencyResolutionSkipper::defaultGACESkipper;
168         } else if (VERSIONED_SKIPPER.equals(skipperMode)) {
169             logger.debug("Collector skip mode enabled: {} (key function GACEV)", skipperMode);
170             skipperSupplier = DependencyResolutionSkipper::defaultGACEVSkipper;
171         } else {
172             throw new IllegalArgumentException("Unknown skipper mode: " + skipperMode + "; known are "
173                     + Arrays.asList(VERSIONLESS_SKIPPER, VERSIONED_SKIPPER, NONE_SKIPPER));
174         }
175 
176         try (DependencyResolutionSkipper skipper = skipperSupplier.get();
177                 ParallelDescriptorResolver parallelDescriptorResolver =
178                         new ParallelDescriptorResolver(SmartExecutorUtils.smartExecutor(
179                                 session,
180                                 null, // we don't know ahead of time; we want global executor
181                                 ConfigUtils.getInteger(session, DEFAULT_THREADS, CONFIG_PROP_THREADS),
182                                 getClass().getSimpleName() + "-"))) {
183             Args args = new Args(session, pool, context, versionContext, request, skipper, parallelDescriptorResolver);
184 
185             DependencySelector rootDepSelector = session.getDependencySelector() != null
186                     ? session.getDependencySelector().deriveChildSelector(context)
187                     : null;
188             DependencyManager rootDepManager = session.getDependencyManager() != null
189                     ? session.getDependencyManager().deriveChildManager(context)
190                     : null;
191             DependencyTraverser rootDepTraverser = session.getDependencyTraverser() != null
192                     ? session.getDependencyTraverser().deriveChildTraverser(context)
193                     : null;
194             VersionFilter rootVerFilter = session.getVersionFilter() != null
195                     ? session.getVersionFilter().deriveChildFilter(context)
196                     : null;
197 
198             List<DependencyNode> parents = Collections.singletonList(node);
199             for (Dependency dependency : dependencies) {
200                 if (rootDepSelector != null && !rootDepSelector.selectDependency(dependency)) {
201                     continue;
202                 }
203                 RequestTrace childTrace =
204                         collectStepTrace(trace, args.request.getRequestContext(), parents, dependency);
205                 DependencyProcessingContext processingContext = new DependencyProcessingContext(
206                         rootDepSelector,
207                         rootDepManager,
208                         rootDepTraverser,
209                         rootVerFilter,
210                         childTrace,
211                         repositories,
212                         managedDependencies,
213                         parents,
214                         dependency,
215                         PremanagedDependency.create(rootDepManager, dependency, false, args.premanagedState));
216                 processingContext.withDependency(processingContext.premanagedDependency.getManagedDependency());
217                 resolveArtifactDescriptorAsync(args, processingContext, results);
218                 args.dependencyProcessingQueue.add(processingContext);
219             }
220 
221             while (!args.dependencyProcessingQueue.isEmpty()) {
222                 processDependency(
223                         args, results, args.dependencyProcessingQueue.remove(), Collections.emptyList(), false);
224             }
225 
226             if (args.interruptedException.get() != null) {
227                 throw new DependencyCollectionException(
228                         results.getResult(), "Collection interrupted", args.interruptedException.get());
229             }
230         }
231     }
232 
233     @SuppressWarnings("checkstyle:parameternumber")
234     private void processDependency(
235             Args args,
236             Results results,
237             DependencyProcessingContext context,
238             List<Artifact> relocations,
239             boolean disableVersionManagement) {
240         if (Thread.interrupted()) {
241             args.interruptedException.set(new InterruptedException());
242         }
243         if (args.interruptedException.get() != null) {
244             return;
245         }
246         Dependency dependency = context.dependency;
247         PremanagedDependency preManaged = context.premanagedDependency;
248 
249         boolean noDescriptor = isLackingDescriptor(args.session, dependency.getArtifact());
250         boolean traverse =
251                 !noDescriptor && (context.depTraverser == null || context.depTraverser.traverseDependency(dependency));
252 
253         Future<DescriptorResolutionResult> resolutionResultFuture = args.resolver.find(dependency.getArtifact());
254         DescriptorResolutionResult resolutionResult;
255         VersionRangeResult rangeResult;
256         try {
257             resolutionResult = resolutionResultFuture.get();
258             rangeResult = resolutionResult.rangeResult;
259         } catch (Exception e) {
260             results.addException(dependency, e, context.parents);
261             return;
262         }
263 
264         Set<Version> versions = resolutionResult.descriptors.keySet();
265         for (Version version : versions) {
266             Artifact originalArtifact = dependency.getArtifact().setVersion(version.toString());
267             Dependency d = dependency.setArtifact(originalArtifact);
268 
269             final ArtifactDescriptorResult descriptorResult = resolutionResult.descriptors.get(version);
270             if (descriptorResult != null) {
271                 d = d.setArtifact(descriptorResult.getArtifact());
272 
273                 int cycleEntry = find(context.parents, d.getArtifact());
274                 if (cycleEntry >= 0) {
275                     results.addCycle(context.parents, cycleEntry, d);
276                     DependencyNode cycleNode = context.parents.get(cycleEntry);
277                     if (cycleNode.getDependency() != null) {
278                         DefaultDependencyNode child = createDependencyNode(
279                                 relocations, preManaged, rangeResult, version, d, descriptorResult, cycleNode);
280                         context.getParent().getChildren().add(child);
281                         continue;
282                     }
283                 }
284 
285                 if (!descriptorResult.getRelocations().isEmpty()) {
286                     if (context.depSelector == null || context.depSelector.selectDependency(d)) {
287                         boolean disableVersionManagementSubsequently = originalArtifact
288                                         .getGroupId()
289                                         .equals(d.getArtifact().getGroupId())
290                                 && originalArtifact
291                                         .getArtifactId()
292                                         .equals(d.getArtifact().getArtifactId());
293 
294                         PremanagedDependency premanagedDependency = PremanagedDependency.create(
295                                 context.depManager, d, disableVersionManagementSubsequently, args.premanagedState);
296                         DependencyProcessingContext relocatedContext = new DependencyProcessingContext(
297                                 context.depSelector,
298                                 context.depManager,
299                                 context.depTraverser,
300                                 context.verFilter,
301                                 context.trace,
302                                 context.repositories,
303                                 descriptorResult.getManagedDependencies(),
304                                 context.parents,
305                                 d,
306                                 premanagedDependency);
307 
308                         relocatedContext.withDependency(premanagedDependency.getManagedDependency());
309                         resolveArtifactDescriptorAsync(args, relocatedContext, results);
310                         processDependency(
311                                 args,
312                                 results,
313                                 relocatedContext,
314                                 descriptorResult.getRelocations(),
315                                 disableVersionManagementSubsequently);
316                     }
317                     return;
318                 } else {
319                     d = args.pool.intern(d.setArtifact(args.pool.intern(d.getArtifact())));
320 
321                     List<RemoteRepository> repos =
322                             getRemoteRepositories(rangeResult.getRepository(version), context.repositories);
323 
324                     DefaultDependencyNode child = createDependencyNode(
325                             relocations,
326                             preManaged,
327                             rangeResult,
328                             version,
329                             d,
330                             descriptorResult.getAliases(),
331                             repos,
332                             args.request.getRequestContext());
333 
334                     context.getParent().getChildren().add(child);
335 
336                     boolean recurse =
337                             traverse && !descriptorResult.getDependencies().isEmpty();
338                     DependencyProcessingContext parentContext = context.withDependency(d);
339                     if (recurse) {
340                         doRecurse(args, parentContext, descriptorResult, child, results, disableVersionManagement);
341                     } else if (!args.skipper.skipResolution(child, parentContext.parents)) {
342                         List<DependencyNode> parents = new ArrayList<>(parentContext.parents.size() + 1);
343                         parents.addAll(parentContext.parents);
344                         parents.add(child);
345                         args.skipper.cache(child, parents);
346                     }
347                 }
348             } else {
349                 List<RemoteRepository> repos =
350                         getRemoteRepositories(rangeResult.getRepository(version), context.repositories);
351                 DefaultDependencyNode child = createDependencyNode(
352                         relocations,
353                         preManaged,
354                         rangeResult,
355                         version,
356                         d,
357                         null,
358                         repos,
359                         args.request.getRequestContext());
360                 context.getParent().getChildren().add(child);
361             }
362         }
363     }
364 
365     @SuppressWarnings("checkstyle:parameternumber")
366     private void doRecurse(
367             Args args,
368             DependencyProcessingContext parentContext,
369             ArtifactDescriptorResult descriptorResult,
370             DefaultDependencyNode child,
371             Results results,
372             boolean disableVersionManagement) {
373         DefaultDependencyCollectionContext context = args.collectionContext.get();
374         args.collectionContext.compareAndSet(
375                 context, context.set(parentContext.dependency, descriptorResult.getManagedDependencies()));
376         context = args.collectionContext.get();
377 
378         DependencySelector childSelector =
379                 parentContext.depSelector != null ? parentContext.depSelector.deriveChildSelector(context) : null;
380         DependencyManager childManager =
381                 parentContext.depManager != null ? parentContext.depManager.deriveChildManager(context) : null;
382         DependencyTraverser childTraverser =
383                 parentContext.depTraverser != null ? parentContext.depTraverser.deriveChildTraverser(context) : null;
384         VersionFilter childFilter =
385                 parentContext.verFilter != null ? parentContext.verFilter.deriveChildFilter(context) : null;
386 
387         final List<RemoteRepository> childRepos = args.ignoreRepos
388                 ? parentContext.repositories
389                 : remoteRepositoryManager.aggregateRepositories(
390                         args.session, parentContext.repositories, descriptorResult.getRepositories(), true);
391 
392         Object key = args.pool.toKey(
393                 parentContext.dependency.getArtifact(),
394                 childRepos,
395                 childSelector,
396                 childManager,
397                 childTraverser,
398                 childFilter);
399 
400         List<DependencyNode> children = args.pool.getChildren(key);
401         if (children == null) {
402             boolean skipResolution = args.skipper.skipResolution(child, parentContext.parents);
403             if (!skipResolution) {
404                 List<DependencyNode> parents = new ArrayList<>(parentContext.parents.size() + 1);
405                 parents.addAll(parentContext.parents);
406                 parents.add(child);
407                 for (Dependency dependency : descriptorResult.getDependencies()) {
408                     if (childSelector != null && !childSelector.selectDependency(dependency)) {
409                         continue;
410                     }
411                     RequestTrace childTrace = collectStepTrace(
412                             parentContext.trace, args.request.getRequestContext(), parents, dependency);
413                     PremanagedDependency premanagedDependency = PremanagedDependency.create(
414                             childManager, dependency, disableVersionManagement, args.premanagedState);
415                     DependencyProcessingContext processingContext = new DependencyProcessingContext(
416                             childSelector,
417                             childManager,
418                             childTraverser,
419                             childFilter,
420                             childTrace,
421                             childRepos,
422                             descriptorResult.getManagedDependencies(),
423                             parents,
424                             dependency,
425                             premanagedDependency);
426                     // resolve descriptors ahead for managed dependency
427                     processingContext.withDependency(processingContext.premanagedDependency.getManagedDependency());
428                     resolveArtifactDescriptorAsync(args, processingContext, results);
429                     args.dependencyProcessingQueue.add(processingContext);
430                 }
431                 args.pool.putChildren(key, child.getChildren());
432                 args.skipper.cache(child, parents);
433             }
434         } else {
435             child.setChildren(children);
436         }
437     }
438 
439     private void resolveArtifactDescriptorAsync(Args args, DependencyProcessingContext context, Results results) {
440         Dependency dependency = context.dependency;
441         args.resolver.resolveDescriptors(dependency.getArtifact(), () -> {
442             VersionRangeRequest rangeRequest = createVersionRangeRequest(
443                     args.request.getRequestContext(), context.trace, context.repositories, dependency);
444             VersionRangeResult rangeResult = cachedResolveRangeResult(rangeRequest, args.pool, args.session);
445             List<? extends Version> versions =
446                     filterVersions(dependency, rangeResult, context.verFilter, args.versionContext);
447 
448             // resolve newer version first to maximize benefits of skipper
449             Collections.reverse(versions);
450 
451             Map<Version, ArtifactDescriptorResult> descriptors = new ConcurrentHashMap<>(versions.size());
452             Stream<? extends Version> stream = versions.size() > 1 ? versions.parallelStream() : versions.stream();
453             stream.forEach(version -> Optional.ofNullable(
454                             resolveDescriptorForVersion(args, context, results, dependency, version))
455                     .ifPresent(r -> descriptors.put(version, r)));
456 
457             DescriptorResolutionResult resolutionResult =
458                     new DescriptorResolutionResult(dependency.getArtifact(), rangeResult);
459             // keep original sequence
460             versions.forEach(version -> resolutionResult.descriptors.put(version, descriptors.get(version)));
461             // populate for versions in version range
462             resolutionResult.flatten().forEach(dr -> args.resolver.cacheVersionRangeDescriptor(dr.artifact, dr));
463 
464             return resolutionResult;
465         });
466     }
467 
468     private ArtifactDescriptorResult resolveDescriptorForVersion(
469             Args args, DependencyProcessingContext context, Results results, Dependency dependency, Version version) {
470         Artifact original = dependency.getArtifact();
471         Artifact newArtifact = original.setVersion(version.toString());
472         Dependency newDependency =
473                 new Dependency(newArtifact, dependency.getScope(), dependency.isOptional(), dependency.getExclusions());
474         DependencyProcessingContext newContext = context.copy();
475 
476         ArtifactDescriptorRequest descriptorRequest = createArtifactDescriptorRequest(
477                 args.request.getRequestContext(), context.trace, newContext.repositories, newDependency);
478         return isLackingDescriptor(args.session, newArtifact)
479                 ? new ArtifactDescriptorResult(descriptorRequest)
480                 : resolveCachedArtifactDescriptor(
481                         args.pool,
482                         descriptorRequest,
483                         args.session,
484                         newContext.withDependency(newDependency).dependency,
485                         results,
486                         context.parents);
487     }
488 
489     static class ParallelDescriptorResolver implements Closeable {
490         private final SmartExecutor smartExecutor;
491 
492         /**
493          * Artifact ID -> Future of DescriptorResolutionResult
494          */
495         private final Map<String, Future<DescriptorResolutionResult>> results = new ConcurrentHashMap<>(256);
496 
497         ParallelDescriptorResolver(SmartExecutor smartExecutor) {
498             this.smartExecutor = smartExecutor;
499         }
500 
501         void resolveDescriptors(Artifact artifact, Callable<DescriptorResolutionResult> callable) {
502             results.computeIfAbsent(ArtifactIdUtils.toId(artifact), key -> smartExecutor.submit(callable));
503         }
504 
505         void cacheVersionRangeDescriptor(Artifact artifact, DescriptorResolutionResult resolutionResult) {
506             results.computeIfAbsent(
507                     ArtifactIdUtils.toId(artifact), key -> CompletableFuture.completedFuture(resolutionResult));
508         }
509 
510         Future<DescriptorResolutionResult> find(Artifact artifact) {
511             return results.get(ArtifactIdUtils.toId(artifact));
512         }
513 
514         @Override
515         public void close() {
516             smartExecutor.close();
517         }
518     }
519 
520     static class DescriptorResolutionResult {
521         Artifact artifact;
522 
523         VersionRangeResult rangeResult;
524 
525         Map<Version, ArtifactDescriptorResult> descriptors;
526 
527         DescriptorResolutionResult(Artifact artifact, VersionRangeResult rangeResult) {
528             this.artifact = artifact;
529             this.rangeResult = rangeResult;
530             this.descriptors = new LinkedHashMap<>(rangeResult.getVersions().size());
531         }
532 
533         DescriptorResolutionResult(
534                 VersionRangeResult rangeResult, Version version, ArtifactDescriptorResult descriptor) {
535             // NOTE: In case of A1 -> A2 relocation this happens:
536             // ArtifactDescriptorResult read by ArtifactDescriptorResultReader for A1
537             // will return instance that will have artifact = A2 (as RelocatedArtifact).
538             // So to properly "key" this instance, we need to use "originally requested" A1 instead!
539             // In short:
540             // ArtifactDescriptorRequest.artifact != ArtifactDescriptorResult.artifact WHEN relocation in play
541             // otherwise (no relocation), they are EQUAL.
542             this(descriptor.getRequest().getArtifact(), rangeResult);
543             this.descriptors.put(version, descriptor);
544         }
545 
546         List<DescriptorResolutionResult> flatten() {
547             if (descriptors.size() > 1) {
548                 return descriptors.entrySet().stream()
549                         .map(e -> new DescriptorResolutionResult(rangeResult, e.getKey(), e.getValue()))
550                         .collect(Collectors.toList());
551             } else {
552                 return Collections.emptyList();
553             }
554         }
555     }
556 
557     static class Args {
558 
559         final RepositorySystemSession session;
560 
561         final boolean ignoreRepos;
562 
563         final boolean premanagedState;
564 
565         final DataPool pool;
566 
567         final Queue<DependencyProcessingContext> dependencyProcessingQueue = new ArrayDeque<>(128);
568 
569         final AtomicReference<DefaultDependencyCollectionContext> collectionContext;
570 
571         final DefaultVersionFilterContext versionContext;
572 
573         final CollectRequest request;
574 
575         final DependencyResolutionSkipper skipper;
576 
577         final ParallelDescriptorResolver resolver;
578 
579         final AtomicReference<InterruptedException> interruptedException;
580 
581         Args(
582                 RepositorySystemSession session,
583                 DataPool pool,
584                 DefaultDependencyCollectionContext collectionContext,
585                 DefaultVersionFilterContext versionContext,
586                 CollectRequest request,
587                 DependencyResolutionSkipper skipper,
588                 ParallelDescriptorResolver resolver) {
589             this.session = session;
590             this.request = request;
591             this.ignoreRepos = session.isIgnoreArtifactDescriptorRepositories();
592             this.premanagedState = ConfigUtils.getBoolean(session, false, DependencyManagerUtils.CONFIG_PROP_VERBOSE);
593             this.pool = pool;
594             this.collectionContext = new AtomicReference<>(collectionContext);
595             this.versionContext = versionContext;
596             this.skipper = skipper;
597             this.resolver = resolver;
598             this.interruptedException = new AtomicReference<>(null);
599         }
600     }
601 }