mirror of https://github.com/apache/maven.git
Cache parent artifact resolution
This commit is contained in:
parent
97518b5b29
commit
8418fb3960
|
@ -304,6 +304,7 @@ under the License.
|
||||||
<!-- END default constructor on Plexus/JSR 330 components -->
|
<!-- END default constructor on Plexus/JSR 330 components -->
|
||||||
<!-- system property with that name no longer evaluated -->
|
<!-- system property with that name no longer evaluated -->
|
||||||
<exclude>org.apache.maven.project.DefaultProjectBuilder#DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY</exclude>
|
<exclude>org.apache.maven.project.DefaultProjectBuilder#DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY</exclude>
|
||||||
|
<exclude>org.apache.maven.project.ProjectModelResolver#ProjectModelResolver(org.eclipse.aether.RepositorySystemSession,org.eclipse.aether.RequestTrace,org.eclipse.aether.RepositorySystem,org.eclipse.aether.impl.RemoteRepositoryManager,java.util.List,org.apache.maven.project.ProjectBuildingRequest$RepositoryMerging,org.apache.maven.project.ReactorModelPool):CONSTRUCTOR_REMOVED</exclude>
|
||||||
<!-- was only a workaround for Plexus Container, hopefully never used by anyone else -->
|
<!-- was only a workaround for Plexus Container, hopefully never used by anyone else -->
|
||||||
<exclude>org.apache.maven.plugin.DefaultBuildPluginManager#setMojoExecutionListeners(java.util.List)</exclude>
|
<exclude>org.apache.maven.plugin.DefaultBuildPluginManager#setMojoExecutionListeners(java.util.List)</exclude>
|
||||||
<!-- could have never been used due to usage of non-export class (CoreExportsProvider) -->
|
<!-- could have never been used due to usage of non-export class (CoreExportsProvider) -->
|
||||||
|
|
|
@ -208,6 +208,7 @@ class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
|
||||||
remoteRepositoryManager,
|
remoteRepositoryManager,
|
||||||
project.getRemoteProjectRepositories(),
|
project.getRemoteProjectRepositories(),
|
||||||
ProjectBuildingRequest.RepositoryMerging.POM_DOMINANT,
|
ProjectBuildingRequest.RepositoryMerging.POM_DOMINANT,
|
||||||
|
null,
|
||||||
null));
|
null));
|
||||||
request.setTransformerContextBuilder(modelBuilder.newTransformerContextBuilder());
|
request.setTransformerContextBuilder(modelBuilder.newTransformerContextBuilder());
|
||||||
request.setSystemProperties(toProperties(session.getSystemProperties()));
|
request.setSystemProperties(toProperties(session.getSystemProperties()));
|
||||||
|
|
|
@ -206,6 +206,7 @@ public class DefaultProjectBuilder implements ProjectBuilder {
|
||||||
private final RepositorySystemSession session;
|
private final RepositorySystemSession session;
|
||||||
private final List<RemoteRepository> repositories;
|
private final List<RemoteRepository> repositories;
|
||||||
private final ReactorModelPool modelPool;
|
private final ReactorModelPool modelPool;
|
||||||
|
private final ConcurrentMap<String, Object> parentCache;
|
||||||
private final TransformerContextBuilder transformerContextBuilder;
|
private final TransformerContextBuilder transformerContextBuilder;
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
|
|
||||||
|
@ -222,6 +223,7 @@ public class DefaultProjectBuilder implements ProjectBuilder {
|
||||||
this.modelPool = null;
|
this.modelPool = null;
|
||||||
this.transformerContextBuilder = null;
|
this.transformerContextBuilder = null;
|
||||||
}
|
}
|
||||||
|
this.parentCache = new ConcurrentHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecutorService createExecutor(int parallelism) {
|
ExecutorService createExecutor(int parallelism) {
|
||||||
|
@ -893,7 +895,8 @@ public class DefaultProjectBuilder implements ProjectBuilder {
|
||||||
repositoryManager,
|
repositoryManager,
|
||||||
repositories,
|
repositories,
|
||||||
request.getRepositoryMerging(),
|
request.getRepositoryMerging(),
|
||||||
modelPool);
|
modelPool,
|
||||||
|
parentCache);
|
||||||
|
|
||||||
modelBuildingRequest.setValidationLevel(request.getValidationLevel());
|
modelBuildingRequest.setValidationLevel(request.getValidationLevel());
|
||||||
modelBuildingRequest.setProcessPlugins(request.isProcessPlugins());
|
modelBuildingRequest.setProcessPlugins(request.isProcessPlugins());
|
||||||
|
|
|
@ -23,7 +23,11 @@ import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import org.apache.maven.api.model.Dependency;
|
import org.apache.maven.api.model.Dependency;
|
||||||
|
@ -57,6 +61,8 @@ import org.eclipse.aether.resolution.VersionRangeResult;
|
||||||
*/
|
*/
|
||||||
public class ProjectModelResolver implements ModelResolver {
|
public class ProjectModelResolver implements ModelResolver {
|
||||||
|
|
||||||
|
private static final int MAX_CAP = 0x7fff;
|
||||||
|
|
||||||
private final RepositorySystemSession session;
|
private final RepositorySystemSession session;
|
||||||
|
|
||||||
private final RequestTrace trace;
|
private final RequestTrace trace;
|
||||||
|
@ -79,6 +85,8 @@ public class ProjectModelResolver implements ModelResolver {
|
||||||
|
|
||||||
private final ProjectBuildingRequest.RepositoryMerging repositoryMerging;
|
private final ProjectBuildingRequest.RepositoryMerging repositoryMerging;
|
||||||
|
|
||||||
|
private final Map<String, ForkJoinTask<Result>> parentCache;
|
||||||
|
|
||||||
public ProjectModelResolver(
|
public ProjectModelResolver(
|
||||||
RepositorySystemSession session,
|
RepositorySystemSession session,
|
||||||
RequestTrace trace,
|
RequestTrace trace,
|
||||||
|
@ -86,7 +94,8 @@ public class ProjectModelResolver implements ModelResolver {
|
||||||
RemoteRepositoryManager remoteRepositoryManager,
|
RemoteRepositoryManager remoteRepositoryManager,
|
||||||
List<RemoteRepository> repositories,
|
List<RemoteRepository> repositories,
|
||||||
ProjectBuildingRequest.RepositoryMerging repositoryMerging,
|
ProjectBuildingRequest.RepositoryMerging repositoryMerging,
|
||||||
ReactorModelPool modelPool) {
|
ReactorModelPool modelPool,
|
||||||
|
Map<String, Object> parentCache) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
this.resolver = resolver;
|
this.resolver = resolver;
|
||||||
|
@ -98,6 +107,7 @@ public class ProjectModelResolver implements ModelResolver {
|
||||||
this.repositoryMerging = repositoryMerging;
|
this.repositoryMerging = repositoryMerging;
|
||||||
this.repositoryIds = new HashSet<>();
|
this.repositoryIds = new HashSet<>();
|
||||||
this.modelPool = modelPool;
|
this.modelPool = modelPool;
|
||||||
|
this.parentCache = parentCache != null ? (Map) parentCache : new ConcurrentHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProjectModelResolver(ProjectModelResolver original) {
|
private ProjectModelResolver(ProjectModelResolver original) {
|
||||||
|
@ -111,6 +121,7 @@ public class ProjectModelResolver implements ModelResolver {
|
||||||
this.repositoryMerging = original.repositoryMerging;
|
this.repositoryMerging = original.repositoryMerging;
|
||||||
this.repositoryIds = new HashSet<>(original.repositoryIds);
|
this.repositoryIds = new HashSet<>(original.repositoryIds);
|
||||||
this.modelPool = original.modelPool;
|
this.modelPool = original.modelPool;
|
||||||
|
this.parentCache = original.parentCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRepository(Repository repository) throws InvalidRepositoryException {
|
public void addRepository(Repository repository) throws InvalidRepositoryException {
|
||||||
|
@ -171,9 +182,62 @@ public class ProjectModelResolver implements ModelResolver {
|
||||||
return new ArtifactModelSource(pomArtifact.getFile(), groupId, artifactId, version);
|
return new ArtifactModelSource(pomArtifact.getFile(), groupId, artifactId, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record Result(ModelSource source, Parent parent, Exception e) {}
|
||||||
|
|
||||||
|
private ForkJoinPool pool = new ForkJoinPool(MAX_CAP);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelSource resolveModel(final Parent parent, AtomicReference<Parent> modified)
|
public ModelSource resolveModel(final Parent parent, AtomicReference<Parent> modified)
|
||||||
throws UnresolvableModelException {
|
throws UnresolvableModelException {
|
||||||
|
Result result;
|
||||||
|
try {
|
||||||
|
ForkJoinTask<Result> future = parentCache.computeIfAbsent(parent.getId(), id -> new ForkJoinTask<>() {
|
||||||
|
Result result;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result getRawResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setRawResult(Result result) {
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean exec() {
|
||||||
|
try {
|
||||||
|
AtomicReference<Parent> modified = new AtomicReference<>();
|
||||||
|
ModelSource source = doResolveModel(parent, modified);
|
||||||
|
result = new Result(source, modified.get(), null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
result = new Result(null, null, e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pool.execute(future);
|
||||||
|
result = future.get();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new UnresolvableModelException(e, parent.getGroupId(), parent.getArtifactId(), parent.getVersion());
|
||||||
|
}
|
||||||
|
if (result.e != null) {
|
||||||
|
uncheckedThrow(result.e);
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
if (result.parent != null && modified != null) {
|
||||||
|
modified.set(result.parent);
|
||||||
|
}
|
||||||
|
return result.source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends Throwable> void uncheckedThrow(Throwable t) throws T {
|
||||||
|
throw (T) t; // rely on vacuous cast
|
||||||
|
}
|
||||||
|
|
||||||
|
private ModelSource doResolveModel(Parent parent, AtomicReference<Parent> modified)
|
||||||
|
throws UnresolvableModelException {
|
||||||
try {
|
try {
|
||||||
final Artifact artifact =
|
final Artifact artifact =
|
||||||
new DefaultArtifact(parent.getGroupId(), parent.getArtifactId(), "", "pom", parent.getVersion());
|
new DefaultArtifact(parent.getGroupId(), parent.getArtifactId(), "", "pom", parent.getVersion());
|
||||||
|
|
|
@ -200,6 +200,7 @@ class ProjectModelResolverTest extends AbstractMavenProjectTestCase {
|
||||||
getContainer().lookup(RemoteRepositoryManager.class),
|
getContainer().lookup(RemoteRepositoryManager.class),
|
||||||
this.getRemoteRepositories(),
|
this.getRemoteRepositories(),
|
||||||
ProjectBuildingRequest.RepositoryMerging.REQUEST_DOMINANT,
|
ProjectBuildingRequest.RepositoryMerging.REQUEST_DOMINANT,
|
||||||
|
null,
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue