From 38a0c20be5e1e27005bc4b2a1a378d6ff7f4a9e9 Mon Sep 17 00:00:00 2001 From: Harald Wellmann Date: Sun, 1 Jul 2018 01:28:33 +0200 Subject: [PATCH 1/7] [MRESOLVER-7] Download dependency POMs in parallel Dependencies are now processed asynchronously by an Executor Cherry-pick commit from PR#2 Nov 1, 2016 --- .../aether/internal/impl/collect/Args.java | 65 ++ .../internal/impl/collect/DataPool.java | 116 +-- .../DefaultDependencyCollectionContext.java | 176 +++- .../collect/DefaultDependencyCollector.java | 814 +++++++----------- .../collect/DependencyCollectionUtils.java | 171 ++++ .../impl/collect/DependencyContext.java | 74 ++ .../impl/collect/PremanagedDependency.java | 112 +++ .../aether/internal/impl/collect/Results.java | 83 ++ .../internal/impl/collect/DataPoolTest.java | 16 +- .../DefaultDependencyCollectorTest.java | 8 +- .../aether/util/concurrency/FutureResult.java | 69 ++ 11 files changed, 1147 insertions(+), 557 deletions(-) create mode 100644 maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/Args.java create mode 100644 maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyCollectionUtils.java create mode 100644 maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyContext.java create mode 100644 maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/PremanagedDependency.java create mode 100644 maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/Results.java create mode 100644 maven-resolver-util/src/main/java/org/eclipse/aether/util/concurrency/FutureResult.java diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/Args.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/Args.java new file mode 100644 index 000000000..be24b221e --- /dev/null +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/Args.java @@ -0,0 +1,65 @@ +package org.eclipse.aether.internal.impl.collect; + +/* + * 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. + */ + +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.RequestTrace; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.util.ConfigUtils; +import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; + +class Args +{ + + final RepositorySystemSession session; + + final boolean ignoreRepos; + + final boolean premanagedState; + + final RequestTrace trace; + + final DataPool pool; + + final NodeStack nodes; + + final DefaultDependencyCollectionContext collectionContext; + + final DefaultVersionFilterContext versionContext; + + final CollectRequest request; + + + Args( RepositorySystemSession session, RequestTrace trace, DataPool pool, NodeStack nodes, + DefaultDependencyCollectionContext collectionContext, DefaultVersionFilterContext versionContext, + CollectRequest request ) + { + this.session = session; + this.request = request; + this.ignoreRepos = session.isIgnoreArtifactDescriptorRepositories(); + this.premanagedState = ConfigUtils.getBoolean( session, false, DependencyManagerUtils.CONFIG_PROP_VERBOSE ); + this.trace = trace; + this.pool = pool; + this.nodes = nodes; + this.collectionContext = collectionContext; + this.versionContext = versionContext; + } + +} \ No newline at end of file diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DataPool.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DataPool.java index a8a8e9ea0..2d286292e 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DataPool.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DataPool.java @@ -19,12 +19,15 @@ * under the License. */ -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.WeakHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import org.eclipse.aether.RepositoryCache; import org.eclipse.aether.RepositorySystemSession; @@ -42,6 +45,7 @@ import org.eclipse.aether.resolution.ArtifactDescriptorResult; import org.eclipse.aether.resolution.VersionRangeRequest; import org.eclipse.aether.resolution.VersionRangeResult; +import org.eclipse.aether.util.concurrency.FutureResult; import org.eclipse.aether.version.Version; import org.eclipse.aether.version.VersionConstraint; @@ -56,8 +60,8 @@ final class DataPool private static final String DESCRIPTORS = DataPool.class.getName() + "$Descriptors"; - public static final ArtifactDescriptorResult NO_DESCRIPTOR = - new ArtifactDescriptorResult( new ArtifactDescriptorRequest() ); + public static final Future NO_DESCRIPTOR = + new FutureResult<>( new ArtifactDescriptorResult( new ArtifactDescriptorRequest() ) ); private ObjectPool artifacts; @@ -65,9 +69,9 @@ final class DataPool private Map descriptors; - private Map constraints = new HashMap(); + private Map constraints = new HashMap<>(); - private Map> nodes = new HashMap>( 256 ); + private Map> nodes = new HashMap<>( 256 ); @SuppressWarnings( "unchecked" ) DataPool( RepositorySystemSession session ) @@ -83,7 +87,7 @@ final class DataPool if ( artifacts == null ) { - artifacts = new ObjectPool(); + artifacts = new ObjectPool<>(); if ( cache != null ) { cache.put( session, ARTIFACT_POOL, artifacts ); @@ -92,7 +96,7 @@ final class DataPool if ( dependencies == null ) { - dependencies = new ObjectPool(); + dependencies = new ObjectPool<>(); if ( cache != null ) { cache.put( session, DEPENDENCY_POOL, dependencies ); @@ -124,7 +128,7 @@ public Object toKey( ArtifactDescriptorRequest request ) return request.getArtifact(); } - public ArtifactDescriptorResult getDescriptor( Object key, ArtifactDescriptorRequest request ) + public Future getDescriptor( Object key, ArtifactDescriptorRequest request ) { Descriptor descriptor = descriptors.get( key ); if ( descriptor != null ) @@ -134,12 +138,12 @@ public ArtifactDescriptorResult getDescriptor( Object key, ArtifactDescriptorReq return null; } - public void putDescriptor( Object key, ArtifactDescriptorResult result ) + public void putDescriptor( Object key, Future futureResult ) { - descriptors.put( key, new GoodDescriptor( result ) ); + descriptors.put( key, new GoodDescriptor( futureResult ) ); } - public void putDescriptor( Object key, ArtifactDescriptorException e ) + public void putDescriptor( Object key, ArtifactDescriptorException exception ) { descriptors.put( key, BadDescriptor.INSTANCE ); } @@ -164,10 +168,10 @@ public void putConstraint( Object key, VersionRangeResult result ) constraints.put( key, new Constraint( result ) ); } - public Object toKey( Artifact artifact, List repositories, DependencySelector selector, - DependencyManager manager, DependencyTraverser traverser, VersionFilter filter ) + public Object toKey( Artifact artifact, DefaultDependencyCollectionContext context ) { - return new GraphKey( artifact, repositories, selector, manager, traverser, filter ); + return new GraphKey( artifact, context.getRepositories(), context.getDepSelector(), + context.getDepManager(), context.getDepTraverser(), context.getVerFilter() ); } public List getChildren( Object key ) @@ -182,67 +186,79 @@ public void putChildren( Object key, List children ) abstract static class Descriptor { - - public abstract ArtifactDescriptorResult toResult( ArtifactDescriptorRequest request ); - + public abstract Future toResult( ArtifactDescriptorRequest request ); } static final class GoodDescriptor extends Descriptor { + Future futureResult; - final Artifact artifact; - - final List relocations; - - final Collection aliases; + GoodDescriptor( Future futureResult ) + { + this.futureResult = futureResult; + } - final List repositories; + public Future toResult( final ArtifactDescriptorRequest request ) + { + return new Future() + { + public boolean cancel( boolean mayInterruptIfRunning ) + { + return futureResult.cancel( mayInterruptIfRunning ); + } - final List dependencies; + public boolean isCancelled() + { + return futureResult.isCancelled(); + } - final List managedDependencies; + public boolean isDone() + { + return futureResult.isDone(); + } - GoodDescriptor( ArtifactDescriptorResult result ) - { - artifact = result.getArtifact(); - relocations = result.getRelocations(); - aliases = result.getAliases(); - dependencies = result.getDependencies(); - managedDependencies = result.getManagedDependencies(); - repositories = result.getRepositories(); + public ArtifactDescriptorResult get() + throws InterruptedException, ExecutionException + { + ArtifactDescriptorResult result = futureResult.get(); + return wrap( request, result ); + } + public ArtifactDescriptorResult get( long timeout, TimeUnit unit ) + throws InterruptedException, ExecutionException, TimeoutException + { + ArtifactDescriptorResult result = futureResult.get( timeout, unit ); + return wrap( request, result ); + } + }; } - public ArtifactDescriptorResult toResult( ArtifactDescriptorRequest request ) + private ArtifactDescriptorResult wrap( ArtifactDescriptorRequest request, ArtifactDescriptorResult result ) { - ArtifactDescriptorResult result = new ArtifactDescriptorResult( request ); - result.setArtifact( artifact ); - result.setRelocations( relocations ); - result.setAliases( aliases ); - result.setDependencies( dependencies ); - result.setManagedDependencies( managedDependencies ); - result.setRepositories( repositories ); - return result; + ArtifactDescriptorResult wrapped = new ArtifactDescriptorResult( request ); + wrapped.setArtifact( result.getArtifact() ); + wrapped.setRelocations( result.getRelocations() ); + wrapped.setAliases( result.getAliases() ); + wrapped.setDependencies( result.getDependencies() ); + wrapped.setManagedDependencies( result.getManagedDependencies() ); + wrapped.setRepositories( result.getRepositories() ); + return wrapped; } - } static final class BadDescriptor extends Descriptor { - static final BadDescriptor INSTANCE = new BadDescriptor(); - public ArtifactDescriptorResult toResult( ArtifactDescriptorRequest request ) + public Future toResult( ArtifactDescriptorRequest request ) { return NO_DESCRIPTOR; } - } static final class Constraint { - final VersionRepo[] repositories; final VersionConstraint versionConstraint; @@ -273,7 +289,6 @@ public VersionRangeResult toResult( VersionRangeRequest request ) static final class VersionRepo { - final Version version; final ArtifactRepository repo; @@ -283,14 +298,11 @@ static final class VersionRepo this.version = version; this.repo = repo; } - } - } static final class ConstraintKey { - private final Artifact artifact; private final List repositories; @@ -361,12 +373,10 @@ public int hashCode() { return hashCode; } - } static final class GraphKey { - private final Artifact artifact; private final List repositories; diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectionContext.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectionContext.java index 3bf4fe1a0..5cc0619c7 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectionContext.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectionContext.java @@ -22,14 +22,22 @@ import java.util.List; import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.RequestTrace; import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.collection.CollectResult; import org.eclipse.aether.collection.DependencyCollectionContext; +import org.eclipse.aether.collection.DependencyManager; +import org.eclipse.aether.collection.DependencySelector; +import org.eclipse.aether.collection.DependencyTraverser; +import org.eclipse.aether.collection.VersionFilter; import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.version.Version; /** * @see DefaultDependencyCollector */ -final class DefaultDependencyCollectionContext +class DefaultDependencyCollectionContext implements DependencyCollectionContext { @@ -40,6 +48,28 @@ final class DefaultDependencyCollectionContext private Dependency dependency; private List managedDependencies; + private CollectResult collectResult; + + private RequestTrace trace; + + private Args args; + + private Results results; + + private List dependencies; + + private List repositories; + + private DependencySelector depSelector; + + private DependencyManager depManager; + + private DependencyTraverser depTraverser; + + private VersionFilter verFilter; + + private Version version; + DefaultDependencyCollectionContext( RepositorySystemSession session, Artifact artifact, Dependency dependency, List managedDependencies ) @@ -50,6 +80,34 @@ final class DefaultDependencyCollectionContext this.managedDependencies = managedDependencies; } + public void prepareDescent() + { + DependencySelector dependencySelector = session.getDependencySelector(); + DependencyManager dependencyManager = session.getDependencyManager(); + VersionFilter versionFilter = session.getVersionFilter(); + setDepSelector( dependencySelector != null ? dependencySelector.deriveChildSelector( this ) : null ); + setDepManager( dependencyManager != null ? dependencyManager.deriveChildManager( this ) : null ); + setDepTraverser( depTraverser != null ? depTraverser.deriveChildTraverser( this ) : null ); + setVerFilter( versionFilter != null ? versionFilter.deriveChildFilter( this ) : null ); + + } + + public DefaultDependencyCollectionContext createChildContext() + { + DefaultDependencyCollectionContext childContext = + new DefaultDependencyCollectionContext( getSession(), getArtifact(), + getDependency(), getManagedDependencies() ); + childContext.depSelector = + getDepSelector() != null ? getDepSelector().deriveChildSelector( this ) : null; + childContext.depManager = + getDepManager() != null ? getDepManager().deriveChildManager( this ) : null; + childContext.depTraverser = + getDepTraverser() != null ? getDepTraverser().deriveChildTraverser( this ) : null; + childContext.verFilter = + getVerFilter() != null ? getVerFilter().deriveChildFilter( this ) : null; + return childContext; + } + public RepositorySystemSession getSession() { return session; @@ -70,13 +128,127 @@ public List getManagedDependencies() return managedDependencies; } - public void set( Dependency dependency, List managedDependencies ) + public CollectResult getCollectResult() + { + return collectResult; + } + + public void setCollectResult( CollectResult collectResult ) + { + this.collectResult = collectResult; + } + + public Args getArgs() + { + return args; + } + + public void setArgs( Args args ) + { + this.args = args; + } + + public Results getResults() + { + return results; + } + + public void setResults( Results results ) + { + this.results = results; + } + + public List getDependencies() + { + return dependencies; + } + + public void setDependencies( List dependencies ) + { + this.dependencies = dependencies; + } + + public List getRepositories() + { + return repositories; + } + + public void setRepositories( List repositories ) + { + this.repositories = repositories; + } + + public DependencySelector getDepSelector() + { + return depSelector; + } + + public void setDepSelector( DependencySelector depSelector ) + { + this.depSelector = depSelector; + } + + public DependencyManager getDepManager() + { + return depManager; + } + + public void setDepManager( DependencyManager depManager ) + { + this.depManager = depManager; + } + + public DependencyTraverser getDepTraverser() + { + return depTraverser; + } + + public void setDepTraverser( DependencyTraverser depTraverser ) + { + this.depTraverser = depTraverser; + } + + public VersionFilter getVerFilter() + { + return verFilter; + } + + public void setVerFilter( VersionFilter verFilter ) + { + this.verFilter = verFilter; + } + + public void setDependency( Dependency dependency ) { artifact = dependency.getArtifact(); this.dependency = dependency; + } + + public void setManagedDependencies( List managedDependencies ) + { this.managedDependencies = managedDependencies; } + public RequestTrace getTrace() + { + return trace; + } + + public void setTrace( RequestTrace trace ) + { + this.trace = trace; + } + + public Version getVersion() + { + return version; + } + + public void setVersion( Version version ) + { + this.version = version; + } + @Override public String toString() { diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java index d2ca7d43f..5feb771c6 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java @@ -8,9 +8,9 @@ * 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 @@ -19,20 +19,28 @@ * under the License. */ +import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.addDependencyNode; +import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.createArtifactDescriptorRequest; +import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.createDependencyNode; +import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.createVersionRangeRequest; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import static java.util.Objects.requireNonNull; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; import javax.inject.Inject; import javax.inject.Named; -import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositoryException; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.RequestTrace; @@ -42,15 +50,11 @@ import org.eclipse.aether.collection.CollectResult; import org.eclipse.aether.collection.DependencyCollectionException; import org.eclipse.aether.collection.DependencyGraphTransformer; -import org.eclipse.aether.collection.DependencyManagement; -import org.eclipse.aether.collection.DependencyManager; -import org.eclipse.aether.collection.DependencySelector; import org.eclipse.aether.collection.DependencyTraverser; import org.eclipse.aether.collection.VersionFilter; import org.eclipse.aether.graph.DefaultDependencyNode; import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyNode; -import org.eclipse.aether.graph.Exclusion; import org.eclipse.aether.impl.ArtifactDescriptorReader; import org.eclipse.aether.impl.DependencyCollector; import org.eclipse.aether.impl.RemoteRepositoryManager; @@ -65,8 +69,7 @@ import org.eclipse.aether.resolution.VersionRangeResult; import org.eclipse.aether.spi.locator.Service; import org.eclipse.aether.spi.locator.ServiceLocator; -import org.eclipse.aether.util.ConfigUtils; -import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; +import org.eclipse.aether.util.concurrency.FutureResult; import org.eclipse.aether.util.graph.transformer.TransformationContextKeys; import org.eclipse.aether.version.Version; import org.slf4j.Logger; @@ -79,9 +82,9 @@ public class DefaultDependencyCollector implements DependencyCollector, Service { - private static final String CONFIG_PROP_MAX_EXCEPTIONS = "aether.dependencyCollector.maxExceptions"; + static final String CONFIG_PROP_MAX_EXCEPTIONS = "aether.dependencyCollector.maxExceptions"; - private static final String CONFIG_PROP_MAX_CYCLES = "aether.dependencyCollector.maxCycles"; + static final String CONFIG_PROP_MAX_CYCLES = "aether.dependencyCollector.maxCycles"; private static final Logger LOGGER = LoggerFactory.getLogger( DefaultDependencyCollector.class ); @@ -91,6 +94,8 @@ public class DefaultDependencyCollector private VersionRangeResolver versionRangeResolver; + private ExecutorService executor = Executors.newFixedThreadPool( 5 ); + public DefaultDependencyCollector() { // enables default constructor @@ -134,87 +139,48 @@ public DefaultDependencyCollector setVersionRangeResolver( VersionRangeResolver public CollectResult collectDependencies( RepositorySystemSession session, CollectRequest request ) throws DependencyCollectionException { - session = optimizeSession( session ); + session = DependencyCollectionUtils.optimizeSession( session ); RequestTrace trace = RequestTrace.newChild( request.getTrace(), request ); CollectResult result = new CollectResult( request ); - DependencySelector depSelector = session.getDependencySelector(); - DependencyManager depManager = session.getDependencyManager(); - DependencyTraverser depTraverser = session.getDependencyTraverser(); - VersionFilter verFilter = session.getVersionFilter(); - Dependency root = request.getRoot(); List repositories = request.getRepositories(); - List dependencies = request.getDependencies(); List managedDependencies = request.getManagedDependencies(); + DefaultDependencyCollectionContext context = + new DefaultDependencyCollectionContext( session, request.getRootArtifact(), root, managedDependencies ); + context.setDependencies( request.getDependencies() ); + context.setCollectResult( result ); + context.setTrace( trace ); + Args args = new Args( session, trace, null, null, context, null, request ); + context.setArgs( args ); + Map stats = LOGGER.isDebugEnabled() ? new LinkedHashMap() : null; long time1 = System.nanoTime(); 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() ); - } - - 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( root.getArtifact() ) ) - { - descriptorResult = new ArtifactDescriptorResult( descriptorRequest ); - } - else - { - descriptorResult = descriptorReader.readArtifactDescriptor( session, descriptorRequest ); - } - } - catch ( ArtifactDescriptorException e ) - { - result.addException( e ); - throw new DependencyCollectionException( result, e.getMessage() ); - } + VersionRangeResult rangeResult = resolveRootVersionRange( context ); + ArtifactDescriptorResult descriptorResult = readRootArtifactDescriptor( context ); root = root.setArtifact( descriptorResult.getArtifact() ); if ( !session.isIgnoreArtifactDescriptorRepositories() ) { repositories = remoteRepositoryManager.aggregateRepositories( session, repositories, - descriptorResult.getRepositories(), - true ); + descriptorResult.getRepositories(), true ); } - dependencies = mergeDeps( dependencies, descriptorResult.getDependencies() ); - managedDependencies = mergeDeps( managedDependencies, descriptorResult.getManagedDependencies() ); + context.setDependencies( mergeDeps( context.getDependencies(), descriptorResult.getDependencies() ) ); + context.setManagedDependencies( mergeDeps( managedDependencies, descriptorResult.getManagedDependencies() ) ); node = new DefaultDependencyNode( root ); node.setRequestContext( request.getRequestContext() ); node.setRelocations( descriptorResult.getRelocations() ); node.setVersionConstraint( rangeResult.getVersionConstraint() ); - node.setVersion( version ); + node.setVersion( context.getVersion() ); node.setAliases( descriptorResult.getAliases() ); node.setRepositories( request.getRepositories() ); } @@ -227,56 +193,41 @@ public CollectResult collectDependencies( RepositorySystemSession session, Colle result.setRoot( node ); + DependencyTraverser depTraverser = session.getDependencyTraverser(); boolean traverse = root == null || depTraverser == null || depTraverser.traverseDependency( root ); String errorPath = null; - if ( traverse && !dependencies.isEmpty() ) + if ( traverse && !context.getDependencies().isEmpty() ) { DataPool pool = new DataPool( session ); NodeStack nodes = new NodeStack(); nodes.push( node ); - DefaultDependencyCollectionContext context = - new DefaultDependencyCollectionContext( session, request.getRootArtifact(), root, managedDependencies ); - DefaultVersionFilterContext versionContext = new DefaultVersionFilterContext( session ); - Args args = new Args( session, trace, pool, nodes, context, versionContext, request ); + args = new Args( session, trace, pool, nodes, context, versionContext, request ); Results results = new Results( result, session ); + context.setArgs( args ); + context.setResults( results ); + context.setRepositories( repositories ); + context.setDepTraverser( depTraverser ); + context.prepareDescent(); - process( args, results, dependencies, repositories, - depSelector != null ? depSelector.deriveChildSelector( context ) : null, - depManager != null ? depManager.deriveChildManager( context ) : null, - depTraverser != null ? depTraverser.deriveChildTraverser( context ) : null, - verFilter != null ? verFilter.deriveChildFilter( context ) : null ); + process( context ); errorPath = results.errorPath; } 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 ); - } - } + transformDependencyGraph( context, stats ); if ( stats != null ) { long time3 = System.nanoTime(); stats.put( "DefaultDependencyCollector.collectTime", time2 - time1 ); stats.put( "DefaultDependencyCollector.transformTime", time3 - time2 ); - LOGGER.debug( "Dependency collection stats: " + stats ); + LOGGER.debug( "Dependency collection stats: {}", stats ); } if ( errorPath != null ) @@ -291,11 +242,80 @@ public CollectResult collectDependencies( RepositorySystemSession session, Colle return result; } - private static RepositorySystemSession optimizeSession( RepositorySystemSession session ) + private VersionRangeResult resolveRootVersionRange( DefaultDependencyCollectionContext context ) + throws DependencyCollectionException { - DefaultRepositorySystemSession optimized = new DefaultRepositorySystemSession( session ); - optimized.setArtifactTypeRegistry( CachingArtifactTypeRegistry.newInstance( session ) ); - return optimized; + CollectRequest request = context.getArgs().request; + RepositorySystemSession session = context.getSession(); + List versions; + VersionRangeResult rangeResult; + Artifact artifact = request.getRoot().getArtifact(); + try + { + VersionRangeRequest rangeRequest = + new VersionRangeRequest( artifact, request.getRepositories(), request.getRequestContext() ); + rangeRequest.setTrace( context.getTrace() ); + rangeResult = versionRangeResolver.resolveVersionRange( session, rangeRequest ); + versions = filterVersions( context.getDependency(), rangeResult, context.getVerFilter(), + new DefaultVersionFilterContext( session ) ); + } + catch ( VersionRangeResolutionException e ) + { + context.getCollectResult().addException( e ); + throw new DependencyCollectionException( context.getCollectResult(), e.getMessage() ); + } + + Version version = versions.get( versions.size() - 1 ); + context.setVersion( version ); + context.setDependency( request.getRoot().setArtifact( artifact.setVersion( version.toString() ) ) ); + return rangeResult; + } + + private ArtifactDescriptorResult readRootArtifactDescriptor( DefaultDependencyCollectionContext context ) + throws DependencyCollectionException + { + CollectRequest request = context.getArgs().request; + Artifact artifact = request.getRoot().getArtifact(); + try + { + ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest(); + descriptorRequest.setArtifact( artifact ); + descriptorRequest.setRepositories( request.getRepositories() ); + descriptorRequest.setRequestContext( request.getRequestContext() ); + descriptorRequest.setTrace( context.getTrace() ); + + ArtifactDescriptorResult descriptorResult = + isLackingDescriptor( artifact ) ? new ArtifactDescriptorResult( descriptorRequest ) + : descriptorReader.readArtifactDescriptor( context.getSession(), descriptorRequest ); + context.setDependency( request.getRoot().setArtifact( descriptorResult.getArtifact() ) ); + return descriptorResult; + } + catch ( ArtifactDescriptorException e ) + { + context.getCollectResult().addException( e ); + throw new DependencyCollectionException( context.getCollectResult(), e.getMessage() ); + } + } + + private void transformDependencyGraph( DefaultDependencyCollectionContext context, Map stats ) + { + RepositorySystemSession session = context.getSession(); + DependencyGraphTransformer transformer = session.getDependencyGraphTransformer(); + if ( transformer != null ) + { + try + { + DefaultDependencyGraphTransformationContext tfContext = + new DefaultDependencyGraphTransformationContext( session ); + tfContext.put( TransformationContextKeys.STATS, stats ); + context.getCollectResult().setRoot( transformer.transformGraph( context.getCollectResult().getRoot(), + tfContext ) ); + } + catch ( RepositoryException e ) + { + context.getCollectResult().addException( e ); + } + } } private List mergeDeps( List dominant, List recessive ) @@ -312,8 +332,8 @@ else if ( recessive == null || recessive.isEmpty() ) else { int initialCapacity = dominant.size() + recessive.size(); - result = new ArrayList( initialCapacity ); - Collection ids = new HashSet( initialCapacity, 1.0f ); + result = new ArrayList<>( initialCapacity ); + Collection ids = new HashSet<>( initialCapacity, 1.0f ); for ( Dependency dependency : dominant ) { ids.add( getId( dependency.getArtifact() ) ); @@ -335,158 +355,215 @@ private static String getId( Artifact a ) return a.getGroupId() + ':' + a.getArtifactId() + ':' + a.getClassifier() + ':' + a.getExtension(); } - private void process( final Args args, Results results, List dependencies, - List repositories, DependencySelector depSelector, - DependencyManager depManager, DependencyTraverser depTraverser, VersionFilter verFilter ) + private void process( DefaultDependencyCollectionContext context ) { - for ( Dependency dependency : dependencies ) + List depContexts = new ArrayList<>(); + for ( Dependency d : context.getDependencies() ) + { + depContexts.add( new DependencyContext( context, d ) ); + } + + List> futures = new ArrayList<>(); + for ( DependencyContext dc : depContexts ) { - processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter, - dependency ); + futures.add( asyncProcessDependency( dc ) ); + } + int pos = 0; + for ( Future future : futures ) + { + try + { + processDependencyNode( future.get() ); + } + catch ( ExecutionException e ) + { + context.getResults().addException( context.getDependencies().get( pos ), (Exception) e.getCause(), + context.getArgs().nodes ); + } + catch ( InterruptedException e ) + { + context.getResults().addException( context.getDependencies().get( pos ), e, context.getArgs().nodes ); + } + pos++; } } - private void processDependency( Args args, Results results, List repositories, - DependencySelector depSelector, DependencyManager depManager, - DependencyTraverser depTraverser, VersionFilter verFilter, Dependency dependency ) + private Future asyncProcessDependency( final DependencyContext dc ) { + return executor.submit( new Callable() + { - List relocations = Collections.emptyList(); - boolean disableVersionManagement = false; - processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter, dependency, - relocations, disableVersionManagement ); + public DependencyContext call() + throws Exception + { + return processDependency( dc ); + } + } ); } - private void processDependency( Args args, Results results, List repositories, - DependencySelector depSelector, DependencyManager depManager, - DependencyTraverser depTraverser, VersionFilter verFilter, Dependency dependency, - List relocations, boolean disableVersionManagement ) + private DependencyContext processDependency( DependencyContext dc ) { + DefaultDependencyCollectionContext context = dc.context; + Args args = context.getArgs(); + Results results = context.getResults(); + + PremanagedDependency preManaged = + PremanagedDependency.create( context.getDepManager(), dc.origDependency, dc.disableVersionManagement, + args.premanagedState ); + Dependency dependency = preManaged.managedDependency; - if ( depSelector != null && !depSelector.selectDependency( dependency ) ) + if ( context.getDepSelector() != null && !context.getDepSelector().selectDependency( dependency ) ) { - return; + return null; } - PremanagedDependency preManaged = - PremanagedDependency.create( depManager, dependency, disableVersionManagement, args.premanagedState ); - dependency = preManaged.managedDependency; - boolean noDescriptor = isLackingDescriptor( dependency.getArtifact() ); - boolean traverse = !noDescriptor && ( depTraverser == null || depTraverser.traverseDependency( dependency ) ); + boolean traverse = !noDescriptor + && ( context.getDepTraverser() == null || context.getDepTraverser().traverseDependency( dependency ) ); - List versions; - VersionRangeResult rangeResult; try { - VersionRangeRequest rangeRequest = createVersionRangeRequest( args, repositories, dependency ); - - rangeResult = cachedResolveRangeResult( rangeRequest, args.pool, args.session ); + VersionRangeRequest rangeRequest = createVersionRangeRequest( args, context.getRepositories(), dependency ); + VersionRangeResult rangeResult = cachedResolveRangeResult( rangeRequest, args.pool, args.session ); + for ( Version version : filterVersions( dependency, rangeResult, context.getVerFilter(), + args.versionContext ) ) + { - versions = filterVersions( dependency, rangeResult, verFilter, args.versionContext ); + Artifact originalArtifact = dependency.getArtifact().setVersion( version.toString() ); + Dependency d = dependency.setArtifact( originalArtifact ); + + ArtifactDescriptorRequest descriptorRequest = + createArtifactDescriptorRequest( args, context.getRepositories(), d ); + + dc.args = args; + dc.preManaged = preManaged; + dc.traverse = traverse; + dc.rangeResult = rangeResult; + dc.version = version; + dc.originalArtifact = originalArtifact; + dc.managedDependency = d; + dc.futureDescriptorResult = + getArtifactDescriptorResult( args, results, noDescriptor, d, descriptorRequest ); + } } catch ( VersionRangeResolutionException e ) { results.addException( dependency, e, args.nodes ); - return; } + return dc; + } - for ( Version version : versions ) + private void processDependencyNode( DependencyContext dc ) + { + if ( dc == null ) { - Artifact originalArtifact = dependency.getArtifact().setVersion( version.toString() ); - Dependency d = dependency.setArtifact( originalArtifact ); - - ArtifactDescriptorRequest descriptorRequest = createArtifactDescriptorRequest( args, repositories, d ); - - final ArtifactDescriptorResult descriptorResult = - getArtifactDescriptorResult( args, results, noDescriptor, d, descriptorRequest ); - if ( descriptorResult != null ) + return; + } + try + { + boolean noResult = dc.futureDescriptorResult == null; + if ( !noResult ) + { + dc.descriptorResult = dc.futureDescriptorResult.get(); + noResult = dc.descriptorResult == null; + } + if ( noResult ) + { + List repos = + getRemoteRepositories( dc.rangeResult.getRepository( dc.version ), dc.context.getRepositories() ); + addDependencyNode( dc.args.nodes.top(), dc.relocations, dc.preManaged, dc.rangeResult, dc.version, + dc.managedDependency, null, repos, dc.args.request.getRequestContext() ); + } + else { - d = d.setArtifact( descriptorResult.getArtifact() ); + processDependencyVersion( dc ); + } + } + catch ( InterruptedException e ) + { + dc.context.getResults().addException( dc.preManaged.managedDependency, e, dc.args.nodes ); + } + catch ( ExecutionException e ) + { + dc.context.getResults().addException( dc.preManaged.managedDependency, (Exception) e.getCause(), + dc.args.nodes ); + } + } - DependencyNode node = args.nodes.top(); + private boolean processDependencyVersion( DependencyContext dc ) + { + Args args = dc.context.getArgs(); + Results results = dc.context.getResults(); + Dependency d = dc.managedDependency.setArtifact( dc.descriptorResult.getArtifact() ); + dc.managedDependency = d; - int cycleEntry = args.nodes.find( d.getArtifact() ); - if ( cycleEntry >= 0 ) - { - results.addCycle( args.nodes, cycleEntry, d ); - DependencyNode cycleNode = args.nodes.get( cycleEntry ); - if ( cycleNode.getDependency() != null ) - { - DefaultDependencyNode child = - createDependencyNode( relocations, preManaged, rangeResult, version, d, descriptorResult, - cycleNode ); - node.getChildren().add( child ); - continue; - } - } + DependencyNode node = args.nodes.top(); - if ( !descriptorResult.getRelocations().isEmpty() ) - { - boolean disableVersionManagementSubsequently = - originalArtifact.getGroupId().equals( d.getArtifact().getGroupId() ) - && originalArtifact.getArtifactId().equals( d.getArtifact().getArtifactId() ); + int cycleEntry = args.nodes.find( d.getArtifact() ); + if ( cycleEntry >= 0 ) + { + results.addCycle( args.nodes, cycleEntry, d ); + DependencyNode cycleNode = args.nodes.get( cycleEntry ); + if ( cycleNode.getDependency() != null ) + { + createDependencyNode( node, dc.relocations, dc.preManaged, dc.rangeResult, dc.version, d, + dc.descriptorResult, cycleNode ); + return true; + } + } - processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter, d, - descriptorResult.getRelocations(), disableVersionManagementSubsequently ); - return; - } - else - { - d = args.pool.intern( d.setArtifact( args.pool.intern( d.getArtifact() ) ) ); + if ( !dc.descriptorResult.getRelocations().isEmpty() ) + { + boolean disableVersionManagementSubsequently = + dc.originalArtifact.getGroupId().equals( d.getArtifact().getGroupId() ) + && dc.originalArtifact.getArtifactId().equals( d.getArtifact().getArtifactId() ); - List repos = - getRemoteRepositories( rangeResult.getRepository( version ), repositories ); + DependencyContext dc2 = new DependencyContext(); + dc2.context = dc.context; + dc2.origDependency = d; + dc2.relocations = dc.descriptorResult.getRelocations(); + dc2.disableVersionManagement = disableVersionManagementSubsequently; + dc2 = processDependency( dc2 ); + processDependencyNode( dc2 ); + return true; + } + else + { + d = args.pool.intern( d ); - DefaultDependencyNode child = - createDependencyNode( relocations, preManaged, rangeResult, version, d, - descriptorResult.getAliases(), repos, args.request.getRequestContext() ); + List repos = + getRemoteRepositories( dc.rangeResult.getRepository( dc.version ), dc.context.getRepositories() ); - node.getChildren().add( child ); + DefaultDependencyNode child = + addDependencyNode( node, dc.relocations, dc.preManaged, dc.rangeResult, dc.version, d, + dc.descriptorResult.getAliases(), repos, args.request.getRequestContext() ); - boolean recurse = traverse && !descriptorResult.getDependencies().isEmpty(); - if ( recurse ) - { - doRecurse( args, results, repositories, depSelector, depManager, depTraverser, verFilter, d, - descriptorResult, child ); - } - } - } - else + if ( dc.traverse && !dc.descriptorResult.getDependencies().isEmpty() ) { - DependencyNode node = args.nodes.top(); - List repos = - getRemoteRepositories( rangeResult.getRepository( version ), repositories ); - DefaultDependencyNode child = - createDependencyNode( relocations, preManaged, rangeResult, version, d, null, repos, - args.request.getRequestContext() ); - node.getChildren().add( child ); + doRecurse( dc.context, d, dc.descriptorResult, child ); } + return false; } } - private void doRecurse( Args args, Results results, List repositories, - DependencySelector depSelector, DependencyManager depManager, - DependencyTraverser depTraverser, VersionFilter verFilter, Dependency d, + private void doRecurse( DefaultDependencyCollectionContext context, Dependency d, ArtifactDescriptorResult descriptorResult, DefaultDependencyNode child ) { - DefaultDependencyCollectionContext context = args.collectionContext; - context.set( d, descriptorResult.getManagedDependencies() ); + context.setDependency( d ); + context.setManagedDependencies( descriptorResult.getManagedDependencies() ); - DependencySelector childSelector = depSelector != null ? depSelector.deriveChildSelector( context ) : null; - DependencyManager childManager = depManager != null ? depManager.deriveChildManager( context ) : null; - DependencyTraverser childTraverser = depTraverser != null ? depTraverser.deriveChildTraverser( context ) : null; - VersionFilter childFilter = verFilter != null ? verFilter.deriveChildFilter( context ) : null; + DefaultDependencyCollectionContext childContext = context.createChildContext(); + new DefaultDependencyCollectionContext( context.getSession(), context.getArtifact(), context.getDependency(), + context.getManagedDependencies() ); + Args args = context.getArgs(); - final List childRepos = - args.ignoreRepos - ? repositories - : remoteRepositoryManager.aggregateRepositories( args.session, repositories, - descriptorResult.getRepositories(), true ); + final List childRepos = args.ignoreRepos ? context.getRepositories() + : remoteRepositoryManager.aggregateRepositories( args.session, context.getRepositories(), + descriptorResult.getRepositories(), true ); + childContext.setRepositories( childRepos ); - Object key = - args.pool.toKey( d.getArtifact(), childRepos, childSelector, childManager, childTraverser, childFilter ); + Object key = args.pool.toKey( d.getArtifact(), childContext ); List children = args.pool.getChildren( key ); if ( children == null ) @@ -495,8 +572,11 @@ private void doRecurse( Args args, Results results, List repos args.nodes.push( child ); - process( args, results, descriptorResult.getDependencies(), childRepos, childSelector, childManager, - childTraverser, childFilter ); + childContext.setArgs( args ); + childContext.setResults( context.getResults() ); + childContext.setDependencies( descriptorResult.getDependencies() ); + + process( childContext ); args.nodes.pop(); } @@ -506,99 +586,54 @@ private void doRecurse( Args args, Results results, List repos } } - private ArtifactDescriptorResult getArtifactDescriptorResult( Args args, Results results, boolean noDescriptor, - Dependency d, - ArtifactDescriptorRequest descriptorRequest ) + private Future getArtifactDescriptorResult( Args args, Results results, + boolean noDescriptor, Dependency d, + ArtifactDescriptorRequest descriptorRequest ) { return noDescriptor - ? new ArtifactDescriptorResult( descriptorRequest ) - : resolveCachedArtifactDescriptor( args.pool, descriptorRequest, args.session, d, results, args ); - + ? new FutureResult( new ArtifactDescriptorResult( descriptorRequest ) ) + : resolveCachedArtifactDescriptor( args.pool, descriptorRequest, args.session, d, results, + args ); } - private ArtifactDescriptorResult resolveCachedArtifactDescriptor( DataPool pool, - ArtifactDescriptorRequest descriptorRequest, - RepositorySystemSession session, Dependency d, - Results results, Args args ) + private Future resolveCachedArtifactDescriptor( final DataPool pool, + final ArtifactDescriptorRequest descriptorRequest, + final RepositorySystemSession session, + final Dependency d, final Results results, + final Args args ) { - Object key = pool.toKey( descriptorRequest ); - ArtifactDescriptorResult descriptorResult = pool.getDescriptor( key, descriptorRequest ); + final Object key = pool.toKey( descriptorRequest ); + Future descriptorResult = pool.getDescriptor( key, descriptorRequest ); if ( descriptorResult == null ) { - try - { - descriptorResult = descriptorReader.readArtifactDescriptor( session, descriptorRequest ); - pool.putDescriptor( key, descriptorResult ); - } - catch ( ArtifactDescriptorException e ) + descriptorResult = executor.submit( new Callable() { - results.addException( d, e, args.nodes ); - pool.putDescriptor( key, e ); - return null; - } + public ArtifactDescriptorResult call() + throws Exception + { + try + { + return descriptorReader.readArtifactDescriptor( session, descriptorRequest ); + } + catch ( ArtifactDescriptorException e ) + { + results.addException( d, e, args.nodes ); + pool.putDescriptor( key, e ); + return null; + } + } + } ); + + pool.putDescriptor( key, descriptorResult ); } else if ( descriptorResult == DataPool.NO_DESCRIPTOR ) { - return null; + return new FutureResult<>( null ); } return descriptorResult; } - - private static DefaultDependencyNode createDependencyNode( List relocations, - PremanagedDependency preManaged, - VersionRangeResult rangeResult, Version version, - Dependency d, Collection aliases, - List repos, String requestContext ) - { - DefaultDependencyNode child = new DefaultDependencyNode( d ); - preManaged.applyTo( child ); - child.setRelocations( relocations ); - child.setVersionConstraint( rangeResult.getVersionConstraint() ); - child.setVersion( version ); - child.setAliases( aliases ); - child.setRepositories( repos ); - child.setRequestContext( requestContext ); - return child; - } - - private static DefaultDependencyNode createDependencyNode( List relocations, - PremanagedDependency preManaged, - VersionRangeResult rangeResult, Version version, - Dependency d, ArtifactDescriptorResult descriptorResult, - DependencyNode cycleNode ) - { - DefaultDependencyNode child = - createDependencyNode( relocations, preManaged, rangeResult, version, d, descriptorResult.getAliases(), - cycleNode.getRepositories(), cycleNode.getRequestContext() ); - child.setChildren( cycleNode.getChildren() ); - return child; - } - - private static ArtifactDescriptorRequest createArtifactDescriptorRequest( Args args, - List repositories, - Dependency d ) - { - ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest(); - descriptorRequest.setArtifact( d.getArtifact() ); - descriptorRequest.setRepositories( repositories ); - descriptorRequest.setRequestContext( args.request.getRequestContext() ); - descriptorRequest.setTrace( args.trace ); - return descriptorRequest; - } - - private static VersionRangeRequest createVersionRangeRequest( Args args, List repositories, - Dependency dependency ) - { - VersionRangeRequest rangeRequest = new VersionRangeRequest(); - rangeRequest.setArtifact( dependency.getArtifact() ); - rangeRequest.setRepositories( repositories ); - rangeRequest.setRequestContext( args.request.getRequestContext() ); - rangeRequest.setTrace( args.trace ); - return rangeRequest; - } - private VersionRangeResult cachedResolveRangeResult( VersionRangeRequest rangeRequest, DataPool pool, RepositorySystemSession session ) throws VersionRangeResolutionException @@ -673,215 +708,4 @@ private static List filterVersions( Dependency dependency, Ve return versions; } - static class Args - { - - final RepositorySystemSession session; - - final boolean ignoreRepos; - - final boolean premanagedState; - - final RequestTrace trace; - - final DataPool pool; - - final NodeStack nodes; - - final DefaultDependencyCollectionContext collectionContext; - - final DefaultVersionFilterContext versionContext; - - final CollectRequest request; - - Args( RepositorySystemSession session, RequestTrace trace, DataPool pool, NodeStack nodes, - DefaultDependencyCollectionContext collectionContext, DefaultVersionFilterContext versionContext, - CollectRequest request ) - { - this.session = session; - this.request = request; - this.ignoreRepos = session.isIgnoreArtifactDescriptorRepositories(); - this.premanagedState = ConfigUtils.getBoolean( session, false, DependencyManagerUtils.CONFIG_PROP_VERBOSE ); - this.trace = trace; - this.pool = pool; - this.nodes = nodes; - this.collectionContext = collectionContext; - this.versionContext = versionContext; - } - - } - - static class Results - { - - private final CollectResult result; - - final int maxExceptions; - - final int maxCycles; - - String errorPath; - - Results( CollectResult result, RepositorySystemSession session ) - { - this.result = result; - this.maxExceptions = ConfigUtils.getInteger( session, 50, CONFIG_PROP_MAX_EXCEPTIONS ); - this.maxCycles = ConfigUtils.getInteger( session, 10, CONFIG_PROP_MAX_CYCLES ); - } - - public void addException( Dependency dependency, Exception e, NodeStack nodes ) - { - if ( maxExceptions < 0 || result.getExceptions().size() < maxExceptions ) - { - result.addException( e ); - if ( errorPath == null ) - { - StringBuilder buffer = new StringBuilder( 256 ); - for ( int i = 0; i < nodes.size(); i++ ) - { - if ( buffer.length() > 0 ) - { - buffer.append( " -> " ); - } - Dependency dep = nodes.get( i ).getDependency(); - if ( dep != null ) - { - buffer.append( dep.getArtifact() ); - } - } - if ( buffer.length() > 0 ) - { - buffer.append( " -> " ); - } - buffer.append( dependency.getArtifact() ); - errorPath = buffer.toString(); - } - } - } - - public void addCycle( NodeStack nodes, int cycleEntry, Dependency dependency ) - { - if ( maxCycles < 0 || result.getCycles().size() < maxCycles ) - { - result.addCycle( new DefaultDependencyCycle( nodes, cycleEntry, dependency ) ); - } - } - - } - - static class PremanagedDependency - { - - final String premanagedVersion; - - final String premanagedScope; - - final Boolean premanagedOptional; - - /** - * @since 1.1.0 - */ - final Collection premanagedExclusions; - - /** - * @since 1.1.0 - */ - final Map premanagedProperties; - - final int managedBits; - - final Dependency managedDependency; - - final boolean premanagedState; - - PremanagedDependency( String premanagedVersion, String premanagedScope, Boolean premanagedOptional, - Collection premanagedExclusions, Map premanagedProperties, - int managedBits, Dependency managedDependency, boolean premanagedState ) - { - this.premanagedVersion = premanagedVersion; - this.premanagedScope = premanagedScope; - this.premanagedOptional = premanagedOptional; - this.premanagedExclusions = - premanagedExclusions != null - ? Collections.unmodifiableCollection( new ArrayList( premanagedExclusions ) ) - : null; - - this.premanagedProperties = - premanagedProperties != null - ? Collections.unmodifiableMap( new HashMap( premanagedProperties ) ) - : null; - - this.managedBits = managedBits; - this.managedDependency = managedDependency; - this.premanagedState = premanagedState; - } - - static PremanagedDependency create( DependencyManager depManager, Dependency dependency, - boolean disableVersionManagement, boolean premanagedState ) - { - DependencyManagement depMngt = depManager != null ? depManager.manageDependency( dependency ) : null; - - int managedBits = 0; - String premanagedVersion = null; - String premanagedScope = null; - Boolean premanagedOptional = null; - Collection premanagedExclusions = null; - Map premanagedProperties = null; - - if ( depMngt != null ) - { - if ( depMngt.getVersion() != null && !disableVersionManagement ) - { - Artifact artifact = dependency.getArtifact(); - premanagedVersion = artifact.getVersion(); - dependency = dependency.setArtifact( artifact.setVersion( depMngt.getVersion() ) ); - managedBits |= DependencyNode.MANAGED_VERSION; - } - if ( depMngt.getProperties() != null ) - { - Artifact artifact = dependency.getArtifact(); - premanagedProperties = artifact.getProperties(); - dependency = dependency.setArtifact( artifact.setProperties( depMngt.getProperties() ) ); - managedBits |= DependencyNode.MANAGED_PROPERTIES; - } - if ( depMngt.getScope() != null ) - { - premanagedScope = dependency.getScope(); - dependency = dependency.setScope( depMngt.getScope() ); - managedBits |= DependencyNode.MANAGED_SCOPE; - } - if ( depMngt.getOptional() != null ) - { - premanagedOptional = dependency.isOptional(); - dependency = dependency.setOptional( depMngt.getOptional() ); - managedBits |= DependencyNode.MANAGED_OPTIONAL; - } - if ( depMngt.getExclusions() != null ) - { - premanagedExclusions = dependency.getExclusions(); - dependency = dependency.setExclusions( depMngt.getExclusions() ); - managedBits |= DependencyNode.MANAGED_EXCLUSIONS; - } - } - return new PremanagedDependency( premanagedVersion, premanagedScope, premanagedOptional, - premanagedExclusions, premanagedProperties, managedBits, dependency, - premanagedState ); - - } - - public void applyTo( DefaultDependencyNode child ) - { - child.setManagedBits( managedBits ); - if ( premanagedState ) - { - child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_VERSION, premanagedVersion ); - child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_SCOPE, premanagedScope ); - child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_OPTIONAL, premanagedOptional ); - child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_EXCLUSIONS, premanagedExclusions ); - child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_PROPERTIES, premanagedProperties ); - } - } - - } - -} +} \ No newline at end of file diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyCollectionUtils.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyCollectionUtils.java new file mode 100644 index 000000000..e919e10d3 --- /dev/null +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyCollectionUtils.java @@ -0,0 +1,171 @@ +package org.eclipse.aether.internal.impl.collect; + +/* + * 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. + */ + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositoryException; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.ArtifactProperties; +import org.eclipse.aether.collection.VersionFilter; +import org.eclipse.aether.graph.DefaultDependencyNode; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.repository.ArtifactRepository; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.resolution.ArtifactDescriptorRequest; +import org.eclipse.aether.resolution.ArtifactDescriptorResult; +import org.eclipse.aether.resolution.VersionRangeRequest; +import org.eclipse.aether.resolution.VersionRangeResolutionException; +import org.eclipse.aether.resolution.VersionRangeResult; +import org.eclipse.aether.version.Version; + +/** + * Utility methods for dependency collection. + * + */ +public class DependencyCollectionUtils +{ + + static DefaultDependencyNode addDependencyNode( DependencyNode parent, List relocations, + PremanagedDependency preManaged, VersionRangeResult rangeResult, + Version version, Dependency d, Collection aliases, + List repos, String requestContext ) + { + DefaultDependencyNode child = new DefaultDependencyNode( d ); + preManaged.applyTo( child ); + child.setRelocations( relocations ); + child.setVersionConstraint( rangeResult.getVersionConstraint() ); + child.setVersion( version ); + child.setAliases( aliases ); + child.setRepositories( repos ); + child.setRequestContext( requestContext ); + parent.getChildren().add( child ); + return child; + } + + static DefaultDependencyNode createDependencyNode( DependencyNode parent, List relocations, + PremanagedDependency preManaged, VersionRangeResult rangeResult, + Version version, Dependency d, + ArtifactDescriptorResult descriptorResult, + DependencyNode cycleNode ) + { + DefaultDependencyNode child = + addDependencyNode( parent, relocations, preManaged, rangeResult, version, d, descriptorResult.getAliases(), + cycleNode.getRepositories(), cycleNode.getRequestContext() ); + child.setChildren( cycleNode.getChildren() ); + return child; + } + + static ArtifactDescriptorRequest createArtifactDescriptorRequest( Args args, List repositories, + Dependency d ) + { + ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest(); + descriptorRequest.setArtifact( d.getArtifact() ); + descriptorRequest.setRepositories( repositories ); + descriptorRequest.setRequestContext( args.request.getRequestContext() ); + descriptorRequest.setTrace( args.trace ); + return descriptorRequest; + } + + static VersionRangeRequest createVersionRangeRequest( Args args, List repositories, + Dependency dependency ) + { + VersionRangeRequest rangeRequest = new VersionRangeRequest(); + rangeRequest.setArtifact( dependency.getArtifact() ); + rangeRequest.setRepositories( repositories ); + rangeRequest.setRequestContext( args.request.getRequestContext() ); + rangeRequest.setTrace( args.trace ); + return rangeRequest; + } + + static boolean isLackingDescriptor( Artifact artifact ) + { + return artifact.getProperty( ArtifactProperties.LOCAL_PATH, null ) != null; + } + + static List getRemoteRepositories( ArtifactRepository repository, + List repositories ) + { + if ( repository instanceof RemoteRepository ) + { + return Collections.singletonList( (RemoteRepository) repository ); + } + if ( repository != null ) + { + return Collections.emptyList(); + } + return repositories; + } + + static List filterVersions( Dependency dependency, VersionRangeResult rangeResult, + VersionFilter verFilter, DefaultVersionFilterContext verContext ) + throws VersionRangeResolutionException + { + if ( rangeResult.getVersions().isEmpty() ) + { + throw new VersionRangeResolutionException( rangeResult, "No versions available for " + + dependency.getArtifact() + " within specified range" ); + } + + List versions; + if ( verFilter != null && rangeResult.getVersionConstraint().getRange() != null ) + { + verContext.set( dependency, rangeResult ); + try + { + verFilter.filterVersions( verContext ); + } + catch ( RepositoryException e ) + { + throw new VersionRangeResolutionException( rangeResult, "Failed to filter versions for " + + dependency.getArtifact() + ": " + e.getMessage(), e ); + } + versions = verContext.get(); + if ( versions.isEmpty() ) + { + throw new VersionRangeResolutionException( rangeResult, "No acceptable versions for " + + dependency.getArtifact() + ": " + rangeResult.getVersions() ); + } + } + else + { + versions = rangeResult.getVersions(); + } + return versions; + } + + static RepositorySystemSession optimizeSession( RepositorySystemSession session ) + { + DefaultRepositorySystemSession optimized = new DefaultRepositorySystemSession( session ); + optimized.setArtifactTypeRegistry( CachingArtifactTypeRegistry.newInstance( session ) ); + return optimized; + } + + static String getId( Dependency d ) + { + Artifact a = d.getArtifact(); + return a.getGroupId() + ':' + a.getArtifactId() + ':' + a.getClassifier() + ':' + a.getExtension(); + } +} \ No newline at end of file diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyContext.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyContext.java new file mode 100644 index 000000000..48af70f20 --- /dev/null +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyContext.java @@ -0,0 +1,74 @@ +package org.eclipse.aether.internal.impl.collect; + +/* + * 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. + */ + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Future; + +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.resolution.ArtifactDescriptorResult; +import org.eclipse.aether.resolution.VersionRangeResult; +import org.eclipse.aether.version.Version; + +class DependencyContext +{ + Dependency origDependency; + + DefaultDependencyCollectionContext context; + + List relocations; + + boolean disableVersionManagement; + + Args args; + + PremanagedDependency preManaged; + + boolean traverse; + + VersionRangeResult rangeResult; + + Version version; + + Artifact originalArtifact; + + Dependency managedDependency; + + Future futureDescriptorResult; + + ArtifactDescriptorResult descriptorResult; + + DependencyContext() + { + // empty + } + + DependencyContext( DefaultDependencyCollectionContext context, Dependency dependency ) + { + this.context = context; + this.origDependency = dependency; + this.relocations = Collections.emptyList(); + this.disableVersionManagement = false; + this.args = context.getArgs(); + } + +} \ No newline at end of file diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/PremanagedDependency.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/PremanagedDependency.java new file mode 100644 index 000000000..860a36a18 --- /dev/null +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/PremanagedDependency.java @@ -0,0 +1,112 @@ +package org.eclipse.aether.internal.impl.collect; + +/* + * 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. + */ + +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.collection.DependencyManagement; +import org.eclipse.aether.collection.DependencyManager; +import org.eclipse.aether.graph.DefaultDependencyNode; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; + +class PremanagedDependency +{ + final String premanagedVersion; + + final String premanagedScope; + + final Boolean premanagedOptional; + + final int managedBits; + + final Dependency managedDependency; + + final boolean premanagedState; + + PremanagedDependency( String premanagedVersion, String premanagedScope, Boolean premanagedOptional, + int managedBits, Dependency managedDependency, boolean premanagedState ) + { + this.premanagedVersion = premanagedVersion; + this.premanagedScope = premanagedScope; + this.premanagedOptional = premanagedOptional; + this.managedBits = managedBits; + this.managedDependency = managedDependency; + this.premanagedState = premanagedState; + } + + static PremanagedDependency create( DependencyManager depManager, Dependency dependency, + boolean disableVersionManagement, boolean premanagedState ) + { + DependencyManagement depMngt = depManager != null ? depManager.manageDependency( dependency ) : null; + + int managedBits = 0; + String premanagedVersion = null; + String premanagedScope = null; + Boolean premanagedOptional = null; + + if ( depMngt != null ) + { + if ( depMngt.getVersion() != null && !disableVersionManagement ) + { + Artifact artifact = dependency.getArtifact(); + premanagedVersion = artifact.getVersion(); + dependency = dependency.setArtifact( artifact.setVersion( depMngt.getVersion() ) ); + managedBits |= DependencyNode.MANAGED_VERSION; + } + if ( depMngt.getProperties() != null ) + { + Artifact artifact = dependency.getArtifact(); + dependency = dependency.setArtifact( artifact.setProperties( depMngt.getProperties() ) ); + managedBits |= DependencyNode.MANAGED_PROPERTIES; + } + if ( depMngt.getScope() != null ) + { + premanagedScope = dependency.getScope(); + dependency = dependency.setScope( depMngt.getScope() ); + managedBits |= DependencyNode.MANAGED_SCOPE; + } + if ( depMngt.getOptional() != null ) + { + premanagedOptional = dependency.isOptional(); + dependency = dependency.setOptional( depMngt.getOptional() ); + managedBits |= DependencyNode.MANAGED_OPTIONAL; + } + if ( depMngt.getExclusions() != null ) + { + dependency = dependency.setExclusions( depMngt.getExclusions() ); + managedBits |= DependencyNode.MANAGED_EXCLUSIONS; + } + } + return new PremanagedDependency( premanagedVersion, premanagedScope, premanagedOptional, managedBits, + dependency, premanagedState ); + } + + public void applyTo( DefaultDependencyNode child ) + { + child.setManagedBits( managedBits ); + if ( premanagedState ) + { + child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_VERSION, premanagedVersion ); + child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_SCOPE, premanagedScope ); + child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_OPTIONAL, premanagedOptional ); + } + } +} \ No newline at end of file diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/Results.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/Results.java new file mode 100644 index 000000000..2d27c9d93 --- /dev/null +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/Results.java @@ -0,0 +1,83 @@ +package org.eclipse.aether.internal.impl.collect; + +/* + * 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. + */ + +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.collection.CollectResult; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.util.ConfigUtils; + +class Results +{ + + private final CollectResult result; + + private final int maxExceptions; + + private final int maxCycles; + + String errorPath; + + Results( CollectResult result, RepositorySystemSession session ) + { + this.result = result; + maxExceptions = ConfigUtils.getInteger( session, 50, DefaultDependencyCollector.CONFIG_PROP_MAX_EXCEPTIONS ); + maxCycles = ConfigUtils.getInteger( session, 10, DefaultDependencyCollector.CONFIG_PROP_MAX_CYCLES ); + } + + public void addException( Dependency dependency, Exception e, NodeStack nodes ) + { + if ( maxExceptions < 0 || result.getExceptions().size() < maxExceptions ) + { + result.addException( e ); + if ( errorPath == null ) + { + StringBuilder buffer = new StringBuilder( 256 ); + for ( int i = 0; i < nodes.size(); i++ ) + { + if ( buffer.length() > 0 ) + { + buffer.append( " -> " ); + } + Dependency dep = nodes.get( i ).getDependency(); + if ( dep != null ) + { + buffer.append( dep.getArtifact() ); + } + } + if ( buffer.length() > 0 ) + { + buffer.append( " -> " ); + } + buffer.append( dependency.getArtifact() ); + errorPath = buffer.toString(); + } + } + } + + public void addCycle( NodeStack nodes, int cycleEntry, Dependency dependency ) + { + if ( maxCycles < 0 || result.getCycles().size() < maxCycles ) + { + result.addCycle( new DefaultDependencyCycle( nodes, cycleEntry, dependency ) ); + } + } + +} \ No newline at end of file diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DataPoolTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DataPoolTest.java index 6b26f339e..2ac18556f 100644 --- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DataPoolTest.java +++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DataPoolTest.java @@ -18,8 +18,11 @@ * specific language governing permissions and limitations * under the License. */ +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.artifact.DefaultArtifact; @@ -27,6 +30,7 @@ import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.resolution.ArtifactDescriptorRequest; import org.eclipse.aether.resolution.ArtifactDescriptorResult; +import org.eclipse.aether.util.concurrency.FutureResult; import org.junit.Test; public class DataPoolTest @@ -38,7 +42,7 @@ private DataPool newDataPool() } @Test - public void testArtifactDescriptorCaching() + public void testArtifactDescriptorCaching() throws InterruptedException, ExecutionException { ArtifactDescriptorRequest request = new ArtifactDescriptorRequest(); request.setArtifact( new DefaultArtifact( "gid:aid:1" ) ); @@ -49,12 +53,14 @@ public void testArtifactDescriptorCaching() result.addManagedDependency( new Dependency( new DefaultArtifact( "gid:mdep:3" ), "runtime" ) ); result.addRepository( new RemoteRepository.Builder( "test", "default", "http://localhost" ).build() ); result.addAlias( new DefaultArtifact( "gid:alias:4" ) ); + Future futureResult = new FutureResult<>( result ); DataPool pool = newDataPool(); Object key = pool.toKey( request ); - pool.putDescriptor( key, result ); - ArtifactDescriptorResult cached = pool.getDescriptor( key, request ); - assertNotNull( cached ); + pool.putDescriptor( key, futureResult ); + Future futureCached = pool.getDescriptor( key, request ); + assertNotNull( futureCached ); + ArtifactDescriptorResult cached = futureCached.get(); assertEquals( result.getArtifact(), cached.getArtifact() ); assertEquals( result.getRelocations(), cached.getRelocations() ); assertEquals( result.getDependencies(), cached.getDependencies() ); diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java index 0e2d6443f..ab6c45c48 100644 --- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java +++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java @@ -18,8 +18,12 @@ * specific language governing permissions and limitations * under the License. */ - -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.IOException; import java.util.ArrayList; diff --git a/maven-resolver-util/src/main/java/org/eclipse/aether/util/concurrency/FutureResult.java b/maven-resolver-util/src/main/java/org/eclipse/aether/util/concurrency/FutureResult.java new file mode 100644 index 000000000..dbbe1df54 --- /dev/null +++ b/maven-resolver-util/src/main/java/org/eclipse/aether/util/concurrency/FutureResult.java @@ -0,0 +1,69 @@ +package org.eclipse.aether.util.concurrency; + +/* + * 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. + */ + +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +/** + * Wraps a result value as a Future. + * + * @param result type + */ +public class FutureResult + implements Future +{ + private final T value; + + public FutureResult( T value ) + { + this.value = value; + } + + @Override + public boolean cancel( boolean mayInterruptIfRunning ) + { + return false; + } + + @Override + public boolean isCancelled() + { + return false; + } + + @Override + public boolean isDone() + { + return true; + } + + @Override + public T get() + { + return value; + } + + @Override + public T get( long timeout, TimeUnit unit ) + { + return value; + } +} From 16a555818d11a80dd3d79a189b86ff539005c56f Mon Sep 17 00:00:00 2001 From: Sylwester Lachiewicz Date: Mon, 30 Jul 2018 23:01:31 +0200 Subject: [PATCH 2/7] [MRESOLVER-7] Use WorkerThreadFactory to create daemon threads --- .../collect/DefaultDependencyCollector.java | 61 +++++-------------- 1 file changed, 16 insertions(+), 45 deletions(-) diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java index 5feb771c6..093f6c929 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java @@ -23,6 +23,7 @@ import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.createArtifactDescriptorRequest; import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.createDependencyNode; import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.createVersionRangeRequest; +import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.filterVersions; import java.util.ArrayList; import java.util.Collection; @@ -35,8 +36,10 @@ import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import javax.inject.Inject; import javax.inject.Named; @@ -51,7 +54,6 @@ import org.eclipse.aether.collection.DependencyCollectionException; import org.eclipse.aether.collection.DependencyGraphTransformer; import org.eclipse.aether.collection.DependencyTraverser; -import org.eclipse.aether.collection.VersionFilter; import org.eclipse.aether.graph.DefaultDependencyNode; import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyNode; @@ -70,6 +72,7 @@ import org.eclipse.aether.spi.locator.Service; import org.eclipse.aether.spi.locator.ServiceLocator; import org.eclipse.aether.util.concurrency.FutureResult; +import org.eclipse.aether.util.concurrency.WorkerThreadFactory; import org.eclipse.aether.util.graph.transformer.TransformationContextKeys; import org.eclipse.aether.version.Version; import org.slf4j.Logger; @@ -94,7 +97,7 @@ public class DefaultDependencyCollector private VersionRangeResolver versionRangeResolver; - private ExecutorService executor = Executors.newFixedThreadPool( 5 ); + private final ExecutorService executor = getExecutor(); public DefaultDependencyCollector() { @@ -136,6 +139,16 @@ public DefaultDependencyCollector setVersionRangeResolver( VersionRangeResolver return this; } + /** + * Setup executor with 5 daemon threads in pool. + */ + private ExecutorService getExecutor( ) + { + return new ThreadPoolExecutor( 5, 5, 3L, TimeUnit.SECONDS, + new LinkedBlockingQueue(), + new WorkerThreadFactory( null ) ); + } + public CollectResult collectDependencies( RepositorySystemSession session, CollectRequest request ) throws DependencyCollectionException { @@ -666,46 +679,4 @@ private static List getRemoteRepositories( ArtifactRepository } return repositories; } - - private static List filterVersions( Dependency dependency, VersionRangeResult rangeResult, - VersionFilter verFilter, - DefaultVersionFilterContext verContext ) - throws VersionRangeResolutionException - { - if ( rangeResult.getVersions().isEmpty() ) - { - throw new VersionRangeResolutionException( rangeResult, - "No versions available for " + dependency.getArtifact() - + " within specified range" ); - } - - List versions; - if ( verFilter != null && rangeResult.getVersionConstraint().getRange() != null ) - { - verContext.set( dependency, rangeResult ); - try - { - verFilter.filterVersions( verContext ); - } - catch ( RepositoryException e ) - { - throw new VersionRangeResolutionException( rangeResult, - "Failed to filter versions for " + dependency.getArtifact() - + ": " + e.getMessage(), e ); - } - versions = verContext.get(); - if ( versions.isEmpty() ) - { - throw new VersionRangeResolutionException( rangeResult, - "No acceptable versions for " + dependency.getArtifact() - + ": " + rangeResult.getVersions() ); - } - } - else - { - versions = rangeResult.getVersions(); - } - return versions; - } - } \ No newline at end of file From 884928f82ac43dad570af15f7896d0a5cf54d2d6 Mon Sep 17 00:00:00 2001 From: Harald Wellmann Date: Sat, 23 Mar 2019 17:04:22 +0100 Subject: [PATCH 3/7] [MRESOLVER-7] select dependencies based on pre-managed state This restores legacy behaviour, but means that dependency management is broken, as noted in MRESOLVER-9. --- .../collect/DefaultDependencyCollector.java | 10 ++--- .../DefaultDependencyCollectorTest.java | 39 +++++++++++++++++++ .../artifact-descriptions/gid3_aid1_1.ini | 7 ++++ .../artifact-descriptions/gid3_aid2_1.ini | 2 + .../artifact-descriptions/gid3_aid3_1.ini | 2 + .../artifact-descriptions/gid3_aid3_2.ini | 2 + 6 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid1_1.ini create mode 100644 maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid2_1.ini create mode 100644 maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid3_1.ini create mode 100644 maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid3_2.ini diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java index 093f6c929..64f3ee0d9 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java @@ -420,16 +420,16 @@ private DependencyContext processDependency( DependencyContext dc ) Args args = context.getArgs(); Results results = context.getResults(); + if ( context.getDepSelector() != null && !context.getDepSelector().selectDependency( dc.origDependency ) ) + { + return null; + } + PremanagedDependency preManaged = PremanagedDependency.create( context.getDepManager(), dc.origDependency, dc.disableVersionManagement, args.premanagedState ); Dependency dependency = preManaged.managedDependency; - if ( context.getDepSelector() != null && !context.getDepSelector().selectDependency( dependency ) ) - { - return null; - } - boolean noDescriptor = isLackingDescriptor( dependency.getArtifact() ); boolean traverse = !noDescriptor diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java index ab6c45c48..a0655ed64 100644 --- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java +++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java @@ -64,6 +64,7 @@ import org.eclipse.aether.util.artifact.ArtifactIdUtils; import org.eclipse.aether.util.graph.manager.ClassicDependencyManager; import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; +import org.eclipse.aether.util.graph.selector.ScopeDependencySelector; import org.eclipse.aether.util.graph.version.HighestVersionFilter; import org.junit.Before; import org.junit.Test; @@ -496,6 +497,44 @@ public void testVersionFilter() assertEquals( 1, result.getRoot().getChildren().size() ); } + /** + * Tests that scope based dependency selection happens before dependency management. + *

+ * This is not really correct (see MRESOLVER-9), but there are a number of tests + * in the Maven and Maven Integration Testing projects that currently rely on this + * behaviour. + */ + @Test + public void testSelectionBeforeManagement() + throws IOException, DependencyCollectionException + { + session.setDependencySelector( new ScopeDependencySelector( "provided", "test" ) ); + session.setDependencyManager( new ClassicDependencyManager() ); + + Dependency dependency = newDep( "gid3:aid1:ext:1", "compile" ); + CollectRequest request = new CollectRequest( dependency, Arrays.asList( repository ) ); + CollectResult result = collector.collectDependencies( session, request ); + + assertEquals( 0, result.getExceptions().size() ); + + DependencyNode root = result.getRoot(); + Dependency newDependency = root.getDependency(); + + assertEquals( dependency, newDependency ); + assertEquals( dependency.getArtifact(), newDependency.getArtifact() ); + + assertEquals( 1, root.getChildren().size() ); + + Dependency expect = newDep( "gid3:aid2:ext:1", "compile" ); + DependencyNode childLevel1 = root.getChildren().get( 0 ); + assertEquals( expect, childLevel1.getDependency() ); + + // With proper dependency management, the test scope of aid3 would + // be managed to compile, and we would get another child. + // Currently, the dependency gets filtered by ScopeDependencyManager. + assertEquals( 0, childLevel1.getChildren().size() ); + } + static class TestDependencyManager implements DependencyManager { diff --git a/maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid1_1.ini b/maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid1_1.ini new file mode 100644 index 000000000..ffc6dbd94 --- /dev/null +++ b/maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid1_1.ini @@ -0,0 +1,7 @@ +[dependencies] +gid3:aid2:ext:1:compile + +[managed-dependencies] +gid3:aid3:ext:1:compile:!optional + + diff --git a/maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid2_1.ini b/maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid2_1.ini new file mode 100644 index 000000000..8d6416603 --- /dev/null +++ b/maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid2_1.ini @@ -0,0 +1,2 @@ +[dependencies] +gid3:aid3:ext:2:test:optional diff --git a/maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid3_1.ini b/maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid3_1.ini new file mode 100644 index 000000000..4322fc62a --- /dev/null +++ b/maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid3_1.ini @@ -0,0 +1,2 @@ +[dependencies] + diff --git a/maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid3_2.ini b/maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid3_2.ini new file mode 100644 index 000000000..4322fc62a --- /dev/null +++ b/maven-resolver-impl/src/test/resources/artifact-descriptions/gid3_aid3_2.ini @@ -0,0 +1,2 @@ +[dependencies] + From 17b369bfef85ad0cbcb3b113ab66de5af4c59dd2 Mon Sep 17 00:00:00 2001 From: Harald Wellmann Date: Sun, 24 Mar 2019 10:19:21 +0100 Subject: [PATCH 4/7] [MRESOLVER-7] deleted redundant code --- .../internal/impl/collect/DefaultDependencyCollector.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java index 64f3ee0d9..b80f949fa 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java @@ -567,8 +567,6 @@ private void doRecurse( DefaultDependencyCollectionContext context, Dependency d context.setManagedDependencies( descriptorResult.getManagedDependencies() ); DefaultDependencyCollectionContext childContext = context.createChildContext(); - new DefaultDependencyCollectionContext( context.getSession(), context.getArtifact(), context.getDependency(), - context.getManagedDependencies() ); Args args = context.getArgs(); final List childRepos = args.ignoreRepos ? context.getRepositories() From b03808806f851e702768b01ac077034401426e70 Mon Sep 17 00:00:00 2001 From: Harald Wellmann Date: Sun, 24 Mar 2019 12:03:22 +0100 Subject: [PATCH 5/7] [MRESOLVER-7] added config property aether.artifact.descriptor.threads Indicates the number of threads used for parallel resolution of artifact descriptors. Default is 5. Set to 1 to revert to serial resolution. maven.artifact.descriptor.threads can be used as alias. --- .../aether/internal/impl/collect/Args.java | 7 ++- .../collect/DefaultDependencyCollector.java | 44 ++++++++++++------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/Args.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/Args.java index be24b221e..f403183fe 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/Args.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/Args.java @@ -19,6 +19,8 @@ * under the License. */ +import java.util.concurrent.ExecutorService; + import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.RequestTrace; import org.eclipse.aether.collection.CollectRequest; @@ -45,11 +47,13 @@ class Args final DefaultVersionFilterContext versionContext; final CollectRequest request; + + final ExecutorService executor; Args( RepositorySystemSession session, RequestTrace trace, DataPool pool, NodeStack nodes, DefaultDependencyCollectionContext collectionContext, DefaultVersionFilterContext versionContext, - CollectRequest request ) + CollectRequest request, ExecutorService executor ) { this.session = session; this.request = request; @@ -60,6 +64,7 @@ class Args this.nodes = nodes; this.collectionContext = collectionContext; this.versionContext = versionContext; + this.executor = executor; } } \ No newline at end of file diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java index b80f949fa..c09ab46ee 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java @@ -71,6 +71,7 @@ import org.eclipse.aether.resolution.VersionRangeResult; import org.eclipse.aether.spi.locator.Service; import org.eclipse.aether.spi.locator.ServiceLocator; +import org.eclipse.aether.util.ConfigUtils; import org.eclipse.aether.util.concurrency.FutureResult; import org.eclipse.aether.util.concurrency.WorkerThreadFactory; import org.eclipse.aether.util.graph.transformer.TransformationContextKeys; @@ -89,6 +90,10 @@ public class DefaultDependencyCollector static final String CONFIG_PROP_MAX_CYCLES = "aether.dependencyCollector.maxCycles"; + private static final String CONFIG_PROP_NUM_ARTIFACT_DESCRIPTOR_THREADS = "aether.artifact.descriptor.threads"; + private static final String CONFIG_PROP_NUM_ARTIFACT_DESCRIPTOR_THREADS_ALT = "maven.artifact.descriptor.threads"; + private static final int DEFAULT_NUM_ARTIFACT_DESCRIPTOR_THREADS = 5; + private static final Logger LOGGER = LoggerFactory.getLogger( DefaultDependencyCollector.class ); private RemoteRepositoryManager remoteRepositoryManager; @@ -97,8 +102,6 @@ public class DefaultDependencyCollector private VersionRangeResolver versionRangeResolver; - private final ExecutorService executor = getExecutor(); - public DefaultDependencyCollector() { // enables default constructor @@ -139,17 +142,27 @@ public DefaultDependencyCollector setVersionRangeResolver( VersionRangeResolver return this; } - /** - * Setup executor with 5 daemon threads in pool. - */ - private ExecutorService getExecutor( ) + public CollectResult collectDependencies( RepositorySystemSession session, CollectRequest request ) + throws DependencyCollectionException { - return new ThreadPoolExecutor( 5, 5, 3L, TimeUnit.SECONDS, - new LinkedBlockingQueue(), - new WorkerThreadFactory( null ) ); + int numThreads = ConfigUtils.getInteger( session, DEFAULT_NUM_ARTIFACT_DESCRIPTOR_THREADS, + CONFIG_PROP_NUM_ARTIFACT_DESCRIPTOR_THREADS, + CONFIG_PROP_NUM_ARTIFACT_DESCRIPTOR_THREADS_ALT ); + LOGGER.debug( "{} = {} ", CONFIG_PROP_NUM_ARTIFACT_DESCRIPTOR_THREADS, numThreads ); + ThreadPoolExecutor executor = new ThreadPoolExecutor( numThreads, numThreads, 3L, TimeUnit.SECONDS, + new LinkedBlockingQueue(), + new WorkerThreadFactory( "artifact-descriptor-resolver" ) ); + try + { + return collectDependenciesWithExecutor( session, request, executor ); + } + finally + { + executor.shutdown(); + } } - - public CollectResult collectDependencies( RepositorySystemSession session, CollectRequest request ) + + private CollectResult collectDependenciesWithExecutor( RepositorySystemSession session, CollectRequest request, ExecutorService executor ) throws DependencyCollectionException { session = DependencyCollectionUtils.optimizeSession( session ); @@ -167,7 +180,8 @@ public CollectResult collectDependencies( RepositorySystemSession session, Colle context.setDependencies( request.getDependencies() ); context.setCollectResult( result ); context.setTrace( trace ); - Args args = new Args( session, trace, null, null, context, null, request ); + + Args args = new Args( session, trace, null, null, context, null, request, executor ); context.setArgs( args ); Map stats = LOGGER.isDebugEnabled() ? new LinkedHashMap() : null; @@ -218,7 +232,7 @@ public CollectResult collectDependencies( RepositorySystemSession session, Colle DefaultVersionFilterContext versionContext = new DefaultVersionFilterContext( session ); - args = new Args( session, trace, pool, nodes, context, versionContext, request ); + args = new Args( session, trace, pool, nodes, context, versionContext, request, executor ); Results results = new Results( result, session ); context.setArgs( args ); context.setResults( results ); @@ -403,7 +417,7 @@ private void process( DefaultDependencyCollectionContext context ) private Future asyncProcessDependency( final DependencyContext dc ) { - return executor.submit( new Callable() + return dc.args.executor.submit( new Callable() { public DependencyContext call() @@ -617,7 +631,7 @@ private Future resolveCachedArtifactDescriptor( final Future descriptorResult = pool.getDescriptor( key, descriptorRequest ); if ( descriptorResult == null ) { - descriptorResult = executor.submit( new Callable() + descriptorResult = args.executor.submit( new Callable() { public ArtifactDescriptorResult call() From 8caf87e9fd953089e378ba4c0dd8bd55a01a1216 Mon Sep 17 00:00:00 2001 From: Harald Wellmann Date: Mon, 25 Mar 2019 21:45:02 +0100 Subject: [PATCH 6/7] [MRESOLVER-7] re-added change of a245b56 ...which got lost in rebasing this branch --- .../impl/collect/PremanagedDependency.java | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/PremanagedDependency.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/PremanagedDependency.java index 860a36a18..5f8169807 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/PremanagedDependency.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/PremanagedDependency.java @@ -19,12 +19,19 @@ * under the License. */ +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.collection.DependencyManagement; import org.eclipse.aether.collection.DependencyManager; import org.eclipse.aether.graph.DefaultDependencyNode; import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.graph.Exclusion; import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; class PremanagedDependency @@ -35,6 +42,16 @@ class PremanagedDependency final Boolean premanagedOptional; + /** + * @since 1.1.0 + */ + final Collection premanagedExclusions; + + /** + * @since 1.1.0 + */ + final Map premanagedProperties; + final int managedBits; final Dependency managedDependency; @@ -42,11 +59,22 @@ class PremanagedDependency final boolean premanagedState; PremanagedDependency( String premanagedVersion, String premanagedScope, Boolean premanagedOptional, + Collection premanagedExclusions, Map premanagedProperties, int managedBits, Dependency managedDependency, boolean premanagedState ) { this.premanagedVersion = premanagedVersion; this.premanagedScope = premanagedScope; this.premanagedOptional = premanagedOptional; + this.premanagedExclusions = + premanagedExclusions != null + ? Collections.unmodifiableCollection( new ArrayList<>( premanagedExclusions ) ) + : null; + + this.premanagedProperties = + premanagedProperties != null + ? Collections.unmodifiableMap( new HashMap<>( premanagedProperties ) ) + : null; + this.managedBits = managedBits; this.managedDependency = managedDependency; this.premanagedState = premanagedState; @@ -61,6 +89,8 @@ static PremanagedDependency create( DependencyManager depManager, Dependency dep String premanagedVersion = null; String premanagedScope = null; Boolean premanagedOptional = null; + Collection premanagedExclusions = null; + Map premanagedProperties = null; if ( depMngt != null ) { @@ -74,6 +104,7 @@ static PremanagedDependency create( DependencyManager depManager, Dependency dep if ( depMngt.getProperties() != null ) { Artifact artifact = dependency.getArtifact(); + premanagedProperties = artifact.getProperties(); dependency = dependency.setArtifact( artifact.setProperties( depMngt.getProperties() ) ); managedBits |= DependencyNode.MANAGED_PROPERTIES; } @@ -91,12 +122,15 @@ static PremanagedDependency create( DependencyManager depManager, Dependency dep } if ( depMngt.getExclusions() != null ) { + premanagedExclusions = dependency.getExclusions(); dependency = dependency.setExclusions( depMngt.getExclusions() ); managedBits |= DependencyNode.MANAGED_EXCLUSIONS; } } - return new PremanagedDependency( premanagedVersion, premanagedScope, premanagedOptional, managedBits, - dependency, premanagedState ); + return new PremanagedDependency( premanagedVersion, premanagedScope, premanagedOptional, + premanagedExclusions, premanagedProperties, managedBits, dependency, + premanagedState ); + } public void applyTo( DefaultDependencyNode child ) @@ -107,6 +141,8 @@ public void applyTo( DefaultDependencyNode child ) child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_VERSION, premanagedVersion ); child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_SCOPE, premanagedScope ); child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_OPTIONAL, premanagedOptional ); + child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_EXCLUSIONS, premanagedExclusions ); + child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_PROPERTIES, premanagedProperties ); } } -} \ No newline at end of file +} From caa8bc3f21cc7ee045d9c55bc96bce6d9acd6bfd Mon Sep 17 00:00:00 2001 From: Harald Wellmann Date: Sun, 31 Mar 2019 18:30:54 +0200 Subject: [PATCH 7/7] [MRESOLVER-7] cleanup after review --- .../internal/impl/collect/DefaultDependencyCollector.java | 4 +--- .../aether/internal/impl/collect/PremanagedDependency.java | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java index c09ab46ee..3d46ba76c 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java @@ -91,7 +91,6 @@ public class DefaultDependencyCollector static final String CONFIG_PROP_MAX_CYCLES = "aether.dependencyCollector.maxCycles"; private static final String CONFIG_PROP_NUM_ARTIFACT_DESCRIPTOR_THREADS = "aether.artifact.descriptor.threads"; - private static final String CONFIG_PROP_NUM_ARTIFACT_DESCRIPTOR_THREADS_ALT = "maven.artifact.descriptor.threads"; private static final int DEFAULT_NUM_ARTIFACT_DESCRIPTOR_THREADS = 5; private static final Logger LOGGER = LoggerFactory.getLogger( DefaultDependencyCollector.class ); @@ -146,8 +145,7 @@ public CollectResult collectDependencies( RepositorySystemSession session, Colle throws DependencyCollectionException { int numThreads = ConfigUtils.getInteger( session, DEFAULT_NUM_ARTIFACT_DESCRIPTOR_THREADS, - CONFIG_PROP_NUM_ARTIFACT_DESCRIPTOR_THREADS, - CONFIG_PROP_NUM_ARTIFACT_DESCRIPTOR_THREADS_ALT ); + CONFIG_PROP_NUM_ARTIFACT_DESCRIPTOR_THREADS ); LOGGER.debug( "{} = {} ", CONFIG_PROP_NUM_ARTIFACT_DESCRIPTOR_THREADS, numThreads ); ThreadPoolExecutor executor = new ThreadPoolExecutor( numThreads, numThreads, 3L, TimeUnit.SECONDS, new LinkedBlockingQueue(), diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/PremanagedDependency.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/PremanagedDependency.java index 5f8169807..222cfe3d4 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/PremanagedDependency.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/PremanagedDependency.java @@ -43,12 +43,12 @@ class PremanagedDependency final Boolean premanagedOptional; /** - * @since 1.1.0 + * @since 1.4.0 */ final Collection premanagedExclusions; /** - * @since 1.1.0 + * @since 1.4.0 */ final Map premanagedProperties;