mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-08-29 03:06:45 +08:00
Refer to Maven Resolver rather than Aether
Closes gh-29255
This commit is contained in:
parent
4eb458f7d8
commit
9cb66d55d1
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -26,6 +26,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import groovy.grape.GrapeEngine;
|
||||
import groovy.lang.GroovyClassLoader;
|
||||
import groovy.lang.GroovyClassLoader.ClassCollector;
|
||||
import groovy.lang.GroovyCodeSource;
|
||||
@ -44,10 +45,9 @@ import org.codehaus.groovy.transform.ASTTransformation;
|
||||
import org.codehaus.groovy.transform.ASTTransformationVisitor;
|
||||
|
||||
import org.springframework.boot.cli.compiler.dependencies.SpringBootDependenciesDependencyManagement;
|
||||
import org.springframework.boot.cli.compiler.grape.AetherGrapeEngine;
|
||||
import org.springframework.boot.cli.compiler.grape.AetherGrapeEngineFactory;
|
||||
import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext;
|
||||
import org.springframework.boot.cli.compiler.grape.GrapeEngineInstaller;
|
||||
import org.springframework.boot.cli.compiler.grape.MavenResolverGrapeEngineFactory;
|
||||
import org.springframework.boot.cli.util.ResourceUtils;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@ -96,7 +96,7 @@ public class GroovyCompiler {
|
||||
DependencyResolutionContext resolutionContext = new DependencyResolutionContext();
|
||||
resolutionContext.addDependencyManagement(new SpringBootDependenciesDependencyManagement());
|
||||
|
||||
AetherGrapeEngine grapeEngine = AetherGrapeEngineFactory.create(this.loader,
|
||||
GrapeEngine grapeEngine = MavenResolverGrapeEngineFactory.create(this.loader,
|
||||
configuration.getRepositoryConfiguration(), resolutionContext, configuration.isQuiet());
|
||||
|
||||
GrapeEngineInstaller.install(grapeEngine);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -16,31 +16,13 @@
|
||||
|
||||
package org.springframework.boot.cli.compiler.grape;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import groovy.grape.GrapeEngine;
|
||||
import groovy.lang.GroovyClassLoader;
|
||||
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||
import org.eclipse.aether.RepositorySystem;
|
||||
import org.eclipse.aether.artifact.Artifact;
|
||||
import org.eclipse.aether.artifact.DefaultArtifact;
|
||||
import org.eclipse.aether.collection.CollectRequest;
|
||||
import org.eclipse.aether.graph.Dependency;
|
||||
import org.eclipse.aether.graph.Exclusion;
|
||||
import org.eclipse.aether.repository.RemoteRepository;
|
||||
import org.eclipse.aether.resolution.ArtifactResolutionException;
|
||||
import org.eclipse.aether.resolution.ArtifactResult;
|
||||
import org.eclipse.aether.resolution.DependencyRequest;
|
||||
import org.eclipse.aether.resolution.DependencyResult;
|
||||
import org.eclipse.aether.util.artifact.JavaScopes;
|
||||
import org.eclipse.aether.util.filter.DependencyFilterUtils;
|
||||
|
||||
/**
|
||||
* A {@link GrapeEngine} implementation that uses
|
||||
@ -50,282 +32,16 @@ import org.eclipse.aether.util.filter.DependencyFilterUtils;
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @since 1.0.0
|
||||
* @deprecated since 2.5.9 for removal in 2.8.0 in favor of
|
||||
* {@link MavenResolverGrapeEngine}
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class AetherGrapeEngine implements GrapeEngine {
|
||||
|
||||
private static final Collection<Exclusion> WILDCARD_EXCLUSION;
|
||||
|
||||
static {
|
||||
List<Exclusion> exclusions = new ArrayList<>();
|
||||
exclusions.add(new Exclusion("*", "*", "*", "*"));
|
||||
WILDCARD_EXCLUSION = Collections.unmodifiableList(exclusions);
|
||||
}
|
||||
|
||||
private final DependencyResolutionContext resolutionContext;
|
||||
|
||||
private final ProgressReporter progressReporter;
|
||||
|
||||
private final GroovyClassLoader classLoader;
|
||||
|
||||
private final DefaultRepositorySystemSession session;
|
||||
|
||||
private final RepositorySystem repositorySystem;
|
||||
|
||||
private final List<RemoteRepository> repositories;
|
||||
@Deprecated
|
||||
public class AetherGrapeEngine extends MavenResolverGrapeEngine {
|
||||
|
||||
public AetherGrapeEngine(GroovyClassLoader classLoader, RepositorySystem repositorySystem,
|
||||
DefaultRepositorySystemSession repositorySystemSession, List<RemoteRepository> remoteRepositories,
|
||||
DependencyResolutionContext resolutionContext, boolean quiet) {
|
||||
this.classLoader = classLoader;
|
||||
this.repositorySystem = repositorySystem;
|
||||
this.session = repositorySystemSession;
|
||||
this.resolutionContext = resolutionContext;
|
||||
this.repositories = new ArrayList<>();
|
||||
List<RemoteRepository> remotes = new ArrayList<>(remoteRepositories);
|
||||
Collections.reverse(remotes); // priority is reversed in addRepository
|
||||
for (RemoteRepository repository : remotes) {
|
||||
addRepository(repository);
|
||||
}
|
||||
this.progressReporter = getProgressReporter(this.session, quiet);
|
||||
}
|
||||
|
||||
private ProgressReporter getProgressReporter(DefaultRepositorySystemSession session, boolean quiet) {
|
||||
String progressReporter = (quiet ? "none"
|
||||
: System.getProperty("org.springframework.boot.cli.compiler.grape.ProgressReporter"));
|
||||
if ("detail".equals(progressReporter) || Boolean.getBoolean("groovy.grape.report.downloads")) {
|
||||
return new DetailedProgressReporter(session, System.out);
|
||||
}
|
||||
if ("none".equals(progressReporter)) {
|
||||
return () -> {
|
||||
};
|
||||
}
|
||||
return new SummaryProgressReporter(session, System.out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object grab(Map args) {
|
||||
return grab(args, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object grab(Map args, Map... dependencyMaps) {
|
||||
List<Exclusion> exclusions = createExclusions(args);
|
||||
List<Dependency> dependencies = createDependencies(dependencyMaps, exclusions);
|
||||
try {
|
||||
List<File> files = resolve(dependencies);
|
||||
GroovyClassLoader classLoader = getClassLoader(args);
|
||||
for (File file : files) {
|
||||
classLoader.addURL(file.toURI().toURL());
|
||||
}
|
||||
}
|
||||
catch (ArtifactResolutionException | MalformedURLException ex) {
|
||||
throw new DependencyResolutionFailedException(ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Exclusion> createExclusions(Map<?, ?> args) {
|
||||
List<Exclusion> exclusions = new ArrayList<>();
|
||||
if (args != null) {
|
||||
List<Map<String, Object>> exclusionMaps = (List<Map<String, Object>>) args.get("excludes");
|
||||
if (exclusionMaps != null) {
|
||||
for (Map<String, Object> exclusionMap : exclusionMaps) {
|
||||
exclusions.add(createExclusion(exclusionMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
return exclusions;
|
||||
}
|
||||
|
||||
private Exclusion createExclusion(Map<String, Object> exclusionMap) {
|
||||
String group = (String) exclusionMap.get("group");
|
||||
String module = (String) exclusionMap.get("module");
|
||||
return new Exclusion(group, module, "*", "*");
|
||||
}
|
||||
|
||||
private List<Dependency> createDependencies(Map<?, ?>[] dependencyMaps, List<Exclusion> exclusions) {
|
||||
List<Dependency> dependencies = new ArrayList<>(dependencyMaps.length);
|
||||
for (Map<?, ?> dependencyMap : dependencyMaps) {
|
||||
dependencies.add(createDependency(dependencyMap, exclusions));
|
||||
}
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
private Dependency createDependency(Map<?, ?> dependencyMap, List<Exclusion> exclusions) {
|
||||
Artifact artifact = createArtifact(dependencyMap);
|
||||
if (isTransitive(dependencyMap)) {
|
||||
return new Dependency(artifact, JavaScopes.COMPILE, false, exclusions);
|
||||
}
|
||||
return new Dependency(artifact, JavaScopes.COMPILE, null, WILDCARD_EXCLUSION);
|
||||
}
|
||||
|
||||
private Artifact createArtifact(Map<?, ?> dependencyMap) {
|
||||
String group = (String) dependencyMap.get("group");
|
||||
String module = (String) dependencyMap.get("module");
|
||||
String version = (String) dependencyMap.get("version");
|
||||
if (version == null) {
|
||||
version = this.resolutionContext.getManagedVersion(group, module);
|
||||
}
|
||||
String classifier = (String) dependencyMap.get("classifier");
|
||||
String type = determineType(dependencyMap);
|
||||
return new DefaultArtifact(group, module, classifier, type, version);
|
||||
}
|
||||
|
||||
private String determineType(Map<?, ?> dependencyMap) {
|
||||
String type = (String) dependencyMap.get("type");
|
||||
String ext = (String) dependencyMap.get("ext");
|
||||
if (type == null) {
|
||||
type = ext;
|
||||
if (type == null) {
|
||||
type = "jar";
|
||||
}
|
||||
}
|
||||
else if (ext != null && !type.equals(ext)) {
|
||||
throw new IllegalArgumentException("If both type and ext are specified they must have the same value");
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private boolean isTransitive(Map<?, ?> dependencyMap) {
|
||||
Boolean transitive = (Boolean) dependencyMap.get("transitive");
|
||||
return (transitive != null) ? transitive : true;
|
||||
}
|
||||
|
||||
private List<Dependency> getDependencies(DependencyResult dependencyResult) {
|
||||
List<Dependency> dependencies = new ArrayList<>();
|
||||
for (ArtifactResult artifactResult : dependencyResult.getArtifactResults()) {
|
||||
dependencies.add(new Dependency(artifactResult.getArtifact(), JavaScopes.COMPILE));
|
||||
}
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
private List<File> getFiles(DependencyResult dependencyResult) {
|
||||
List<File> files = new ArrayList<>();
|
||||
for (ArtifactResult result : dependencyResult.getArtifactResults()) {
|
||||
files.add(result.getArtifact().getFile());
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
private GroovyClassLoader getClassLoader(Map args) {
|
||||
GroovyClassLoader classLoader = (GroovyClassLoader) args.get("classLoader");
|
||||
return (classLoader != null) ? classLoader : this.classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResolver(Map<String, Object> args) {
|
||||
String name = (String) args.get("name");
|
||||
String root = (String) args.get("root");
|
||||
RemoteRepository.Builder builder = new RemoteRepository.Builder(name, "default", root);
|
||||
RemoteRepository repository = builder.build();
|
||||
addRepository(repository);
|
||||
}
|
||||
|
||||
protected void addRepository(RemoteRepository repository) {
|
||||
if (this.repositories.contains(repository)) {
|
||||
return;
|
||||
}
|
||||
repository = getPossibleMirror(repository);
|
||||
repository = applyProxy(repository);
|
||||
repository = applyAuthentication(repository);
|
||||
this.repositories.add(0, repository);
|
||||
}
|
||||
|
||||
private RemoteRepository getPossibleMirror(RemoteRepository remoteRepository) {
|
||||
RemoteRepository mirror = this.session.getMirrorSelector().getMirror(remoteRepository);
|
||||
if (mirror != null) {
|
||||
return mirror;
|
||||
}
|
||||
return remoteRepository;
|
||||
}
|
||||
|
||||
private RemoteRepository applyProxy(RemoteRepository repository) {
|
||||
if (repository.getProxy() == null) {
|
||||
RemoteRepository.Builder builder = new RemoteRepository.Builder(repository);
|
||||
builder.setProxy(this.session.getProxySelector().getProxy(repository));
|
||||
repository = builder.build();
|
||||
}
|
||||
return repository;
|
||||
}
|
||||
|
||||
private RemoteRepository applyAuthentication(RemoteRepository repository) {
|
||||
if (repository.getAuthentication() == null) {
|
||||
RemoteRepository.Builder builder = new RemoteRepository.Builder(repository);
|
||||
builder.setAuthentication(this.session.getAuthenticationSelector().getAuthentication(repository));
|
||||
repository = builder.build();
|
||||
}
|
||||
return repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, List<String>>> enumerateGrapes() {
|
||||
throw new UnsupportedOperationException("Grape enumeration is not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI[] resolve(Map args, Map... dependencyMaps) {
|
||||
return resolve(args, null, dependencyMaps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI[] resolve(Map args, List depsInfo, Map... dependencyMaps) {
|
||||
List<Exclusion> exclusions = createExclusions(args);
|
||||
List<Dependency> dependencies = createDependencies(dependencyMaps, exclusions);
|
||||
try {
|
||||
List<File> files = resolve(dependencies);
|
||||
List<URI> uris = new ArrayList<>(files.size());
|
||||
for (File file : files) {
|
||||
uris.add(file.toURI());
|
||||
}
|
||||
return uris.toArray(new URI[0]);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new DependencyResolutionFailedException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private List<File> resolve(List<Dependency> dependencies) throws ArtifactResolutionException {
|
||||
try {
|
||||
CollectRequest collectRequest = getCollectRequest(dependencies);
|
||||
DependencyRequest dependencyRequest = getDependencyRequest(collectRequest);
|
||||
DependencyResult result = this.repositorySystem.resolveDependencies(this.session, dependencyRequest);
|
||||
addManagedDependencies(result);
|
||||
return getFiles(result);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new DependencyResolutionFailedException(ex);
|
||||
}
|
||||
finally {
|
||||
this.progressReporter.finished();
|
||||
}
|
||||
}
|
||||
|
||||
private CollectRequest getCollectRequest(List<Dependency> dependencies) {
|
||||
CollectRequest collectRequest = new CollectRequest((Dependency) null, dependencies,
|
||||
new ArrayList<>(this.repositories));
|
||||
collectRequest.setManagedDependencies(this.resolutionContext.getManagedDependencies());
|
||||
return collectRequest;
|
||||
}
|
||||
|
||||
private DependencyRequest getDependencyRequest(CollectRequest collectRequest) {
|
||||
return new DependencyRequest(collectRequest,
|
||||
DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE, JavaScopes.RUNTIME));
|
||||
}
|
||||
|
||||
private void addManagedDependencies(DependencyResult result) {
|
||||
this.resolutionContext.addManagedDependencies(getDependencies(result));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map[] listDependencies(ClassLoader classLoader) {
|
||||
throw new UnsupportedOperationException("Listing dependencies is not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object grab(String endorsedModule) {
|
||||
throw new UnsupportedOperationException("Grabbing an endorsed module is not supported");
|
||||
super(classLoader, repositorySystem, repositorySystemSession, remoteRepositories, resolutionContext, quiet);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -40,7 +40,10 @@ import org.eclipse.aether.transport.http.HttpTransporterFactory;
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.0.0
|
||||
* @deprecated since 2.5.9 for removal in 2.8.0 in favor of
|
||||
* {@link MavenResolverGrapeEngineFactory}
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AetherGrapeEngineFactory {
|
||||
|
||||
public static AetherGrapeEngine create(GroovyClassLoader classLoader,
|
||||
|
@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.cli.compiler.grape;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import groovy.grape.GrapeEngine;
|
||||
import groovy.lang.GroovyClassLoader;
|
||||
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||
import org.eclipse.aether.RepositorySystem;
|
||||
import org.eclipse.aether.artifact.Artifact;
|
||||
import org.eclipse.aether.artifact.DefaultArtifact;
|
||||
import org.eclipse.aether.collection.CollectRequest;
|
||||
import org.eclipse.aether.graph.Dependency;
|
||||
import org.eclipse.aether.graph.Exclusion;
|
||||
import org.eclipse.aether.repository.RemoteRepository;
|
||||
import org.eclipse.aether.resolution.ArtifactResolutionException;
|
||||
import org.eclipse.aether.resolution.ArtifactResult;
|
||||
import org.eclipse.aether.resolution.DependencyRequest;
|
||||
import org.eclipse.aether.resolution.DependencyResult;
|
||||
import org.eclipse.aether.util.artifact.JavaScopes;
|
||||
import org.eclipse.aether.util.filter.DependencyFilterUtils;
|
||||
|
||||
/**
|
||||
* A {@link GrapeEngine} implementation that uses
|
||||
* <a href="https://maven.apache.org/resolver/index.html">Maven Resolver</a>, the
|
||||
* dependency resolution system used by Maven.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Phillip Webb
|
||||
* @since 2.5.9
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class MavenResolverGrapeEngine implements GrapeEngine {
|
||||
|
||||
private static final Collection<Exclusion> WILDCARD_EXCLUSION;
|
||||
|
||||
static {
|
||||
List<Exclusion> exclusions = new ArrayList<>();
|
||||
exclusions.add(new Exclusion("*", "*", "*", "*"));
|
||||
WILDCARD_EXCLUSION = Collections.unmodifiableList(exclusions);
|
||||
}
|
||||
|
||||
private final DependencyResolutionContext resolutionContext;
|
||||
|
||||
private final ProgressReporter progressReporter;
|
||||
|
||||
private final GroovyClassLoader classLoader;
|
||||
|
||||
private final DefaultRepositorySystemSession session;
|
||||
|
||||
private final RepositorySystem repositorySystem;
|
||||
|
||||
private final List<RemoteRepository> repositories;
|
||||
|
||||
public MavenResolverGrapeEngine(GroovyClassLoader classLoader, RepositorySystem repositorySystem,
|
||||
DefaultRepositorySystemSession repositorySystemSession, List<RemoteRepository> remoteRepositories,
|
||||
DependencyResolutionContext resolutionContext, boolean quiet) {
|
||||
this.classLoader = classLoader;
|
||||
this.repositorySystem = repositorySystem;
|
||||
this.session = repositorySystemSession;
|
||||
this.resolutionContext = resolutionContext;
|
||||
this.repositories = new ArrayList<>();
|
||||
List<RemoteRepository> remotes = new ArrayList<>(remoteRepositories);
|
||||
Collections.reverse(remotes); // priority is reversed in addRepository
|
||||
for (RemoteRepository repository : remotes) {
|
||||
addRepository(repository);
|
||||
}
|
||||
this.progressReporter = getProgressReporter(this.session, quiet);
|
||||
}
|
||||
|
||||
private ProgressReporter getProgressReporter(DefaultRepositorySystemSession session, boolean quiet) {
|
||||
String progressReporter = (quiet ? "none"
|
||||
: System.getProperty("org.springframework.boot.cli.compiler.grape.ProgressReporter"));
|
||||
if ("detail".equals(progressReporter) || Boolean.getBoolean("groovy.grape.report.downloads")) {
|
||||
return new DetailedProgressReporter(session, System.out);
|
||||
}
|
||||
if ("none".equals(progressReporter)) {
|
||||
return () -> {
|
||||
};
|
||||
}
|
||||
return new SummaryProgressReporter(session, System.out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object grab(Map args) {
|
||||
return grab(args, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object grab(Map args, Map... dependencyMaps) {
|
||||
List<Exclusion> exclusions = createExclusions(args);
|
||||
List<Dependency> dependencies = createDependencies(dependencyMaps, exclusions);
|
||||
try {
|
||||
List<File> files = resolve(dependencies);
|
||||
GroovyClassLoader classLoader = getClassLoader(args);
|
||||
for (File file : files) {
|
||||
classLoader.addURL(file.toURI().toURL());
|
||||
}
|
||||
}
|
||||
catch (ArtifactResolutionException | MalformedURLException ex) {
|
||||
throw new DependencyResolutionFailedException(ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Exclusion> createExclusions(Map<?, ?> args) {
|
||||
List<Exclusion> exclusions = new ArrayList<>();
|
||||
if (args != null) {
|
||||
List<Map<String, Object>> exclusionMaps = (List<Map<String, Object>>) args.get("excludes");
|
||||
if (exclusionMaps != null) {
|
||||
for (Map<String, Object> exclusionMap : exclusionMaps) {
|
||||
exclusions.add(createExclusion(exclusionMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
return exclusions;
|
||||
}
|
||||
|
||||
private Exclusion createExclusion(Map<String, Object> exclusionMap) {
|
||||
String group = (String) exclusionMap.get("group");
|
||||
String module = (String) exclusionMap.get("module");
|
||||
return new Exclusion(group, module, "*", "*");
|
||||
}
|
||||
|
||||
private List<Dependency> createDependencies(Map<?, ?>[] dependencyMaps, List<Exclusion> exclusions) {
|
||||
List<Dependency> dependencies = new ArrayList<>(dependencyMaps.length);
|
||||
for (Map<?, ?> dependencyMap : dependencyMaps) {
|
||||
dependencies.add(createDependency(dependencyMap, exclusions));
|
||||
}
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
private Dependency createDependency(Map<?, ?> dependencyMap, List<Exclusion> exclusions) {
|
||||
Artifact artifact = createArtifact(dependencyMap);
|
||||
if (isTransitive(dependencyMap)) {
|
||||
return new Dependency(artifact, JavaScopes.COMPILE, false, exclusions);
|
||||
}
|
||||
return new Dependency(artifact, JavaScopes.COMPILE, null, WILDCARD_EXCLUSION);
|
||||
}
|
||||
|
||||
private Artifact createArtifact(Map<?, ?> dependencyMap) {
|
||||
String group = (String) dependencyMap.get("group");
|
||||
String module = (String) dependencyMap.get("module");
|
||||
String version = (String) dependencyMap.get("version");
|
||||
if (version == null) {
|
||||
version = this.resolutionContext.getManagedVersion(group, module);
|
||||
}
|
||||
String classifier = (String) dependencyMap.get("classifier");
|
||||
String type = determineType(dependencyMap);
|
||||
return new DefaultArtifact(group, module, classifier, type, version);
|
||||
}
|
||||
|
||||
private String determineType(Map<?, ?> dependencyMap) {
|
||||
String type = (String) dependencyMap.get("type");
|
||||
String ext = (String) dependencyMap.get("ext");
|
||||
if (type == null) {
|
||||
type = ext;
|
||||
if (type == null) {
|
||||
type = "jar";
|
||||
}
|
||||
}
|
||||
else if (ext != null && !type.equals(ext)) {
|
||||
throw new IllegalArgumentException("If both type and ext are specified they must have the same value");
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private boolean isTransitive(Map<?, ?> dependencyMap) {
|
||||
Boolean transitive = (Boolean) dependencyMap.get("transitive");
|
||||
return (transitive != null) ? transitive : true;
|
||||
}
|
||||
|
||||
private List<Dependency> getDependencies(DependencyResult dependencyResult) {
|
||||
List<Dependency> dependencies = new ArrayList<>();
|
||||
for (ArtifactResult artifactResult : dependencyResult.getArtifactResults()) {
|
||||
dependencies.add(new Dependency(artifactResult.getArtifact(), JavaScopes.COMPILE));
|
||||
}
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
private List<File> getFiles(DependencyResult dependencyResult) {
|
||||
List<File> files = new ArrayList<>();
|
||||
for (ArtifactResult result : dependencyResult.getArtifactResults()) {
|
||||
files.add(result.getArtifact().getFile());
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
private GroovyClassLoader getClassLoader(Map args) {
|
||||
GroovyClassLoader classLoader = (GroovyClassLoader) args.get("classLoader");
|
||||
return (classLoader != null) ? classLoader : this.classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResolver(Map<String, Object> args) {
|
||||
String name = (String) args.get("name");
|
||||
String root = (String) args.get("root");
|
||||
RemoteRepository.Builder builder = new RemoteRepository.Builder(name, "default", root);
|
||||
RemoteRepository repository = builder.build();
|
||||
addRepository(repository);
|
||||
}
|
||||
|
||||
protected void addRepository(RemoteRepository repository) {
|
||||
if (this.repositories.contains(repository)) {
|
||||
return;
|
||||
}
|
||||
repository = getPossibleMirror(repository);
|
||||
repository = applyProxy(repository);
|
||||
repository = applyAuthentication(repository);
|
||||
this.repositories.add(0, repository);
|
||||
}
|
||||
|
||||
private RemoteRepository getPossibleMirror(RemoteRepository remoteRepository) {
|
||||
RemoteRepository mirror = this.session.getMirrorSelector().getMirror(remoteRepository);
|
||||
if (mirror != null) {
|
||||
return mirror;
|
||||
}
|
||||
return remoteRepository;
|
||||
}
|
||||
|
||||
private RemoteRepository applyProxy(RemoteRepository repository) {
|
||||
if (repository.getProxy() == null) {
|
||||
RemoteRepository.Builder builder = new RemoteRepository.Builder(repository);
|
||||
builder.setProxy(this.session.getProxySelector().getProxy(repository));
|
||||
repository = builder.build();
|
||||
}
|
||||
return repository;
|
||||
}
|
||||
|
||||
private RemoteRepository applyAuthentication(RemoteRepository repository) {
|
||||
if (repository.getAuthentication() == null) {
|
||||
RemoteRepository.Builder builder = new RemoteRepository.Builder(repository);
|
||||
builder.setAuthentication(this.session.getAuthenticationSelector().getAuthentication(repository));
|
||||
repository = builder.build();
|
||||
}
|
||||
return repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, List<String>>> enumerateGrapes() {
|
||||
throw new UnsupportedOperationException("Grape enumeration is not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI[] resolve(Map args, Map... dependencyMaps) {
|
||||
return resolve(args, null, dependencyMaps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI[] resolve(Map args, List depsInfo, Map... dependencyMaps) {
|
||||
List<Exclusion> exclusions = createExclusions(args);
|
||||
List<Dependency> dependencies = createDependencies(dependencyMaps, exclusions);
|
||||
try {
|
||||
List<File> files = resolve(dependencies);
|
||||
List<URI> uris = new ArrayList<>(files.size());
|
||||
for (File file : files) {
|
||||
uris.add(file.toURI());
|
||||
}
|
||||
return uris.toArray(new URI[0]);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new DependencyResolutionFailedException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private List<File> resolve(List<Dependency> dependencies) throws ArtifactResolutionException {
|
||||
try {
|
||||
CollectRequest collectRequest = getCollectRequest(dependencies);
|
||||
DependencyRequest dependencyRequest = getDependencyRequest(collectRequest);
|
||||
DependencyResult result = this.repositorySystem.resolveDependencies(this.session, dependencyRequest);
|
||||
addManagedDependencies(result);
|
||||
return getFiles(result);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new DependencyResolutionFailedException(ex);
|
||||
}
|
||||
finally {
|
||||
this.progressReporter.finished();
|
||||
}
|
||||
}
|
||||
|
||||
private CollectRequest getCollectRequest(List<Dependency> dependencies) {
|
||||
CollectRequest collectRequest = new CollectRequest((Dependency) null, dependencies,
|
||||
new ArrayList<>(this.repositories));
|
||||
collectRequest.setManagedDependencies(this.resolutionContext.getManagedDependencies());
|
||||
return collectRequest;
|
||||
}
|
||||
|
||||
private DependencyRequest getDependencyRequest(CollectRequest collectRequest) {
|
||||
return new DependencyRequest(collectRequest,
|
||||
DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE, JavaScopes.RUNTIME));
|
||||
}
|
||||
|
||||
private void addManagedDependencies(DependencyResult result) {
|
||||
this.resolutionContext.addManagedDependencies(getDependencies(result));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map[] listDependencies(ClassLoader classLoader) {
|
||||
throw new UnsupportedOperationException("Listing dependencies is not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object grab(String endorsedModule) {
|
||||
throw new UnsupportedOperationException("Grabbing an endorsed module is not supported");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.cli.compiler.grape;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import groovy.lang.GroovyClassLoader;
|
||||
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
|
||||
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||
import org.eclipse.aether.RepositorySystem;
|
||||
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
|
||||
import org.eclipse.aether.impl.DefaultServiceLocator;
|
||||
import org.eclipse.aether.internal.impl.DefaultRepositorySystem;
|
||||
import org.eclipse.aether.repository.RemoteRepository;
|
||||
import org.eclipse.aether.repository.RepositoryPolicy;
|
||||
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
|
||||
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
|
||||
import org.eclipse.aether.spi.locator.ServiceLocator;
|
||||
import org.eclipse.aether.transport.file.FileTransporterFactory;
|
||||
import org.eclipse.aether.transport.http.HttpTransporterFactory;
|
||||
|
||||
/**
|
||||
* Utility class to create a pre-configured {@link MavenResolverGrapeEngine}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.5.9
|
||||
*/
|
||||
public abstract class MavenResolverGrapeEngineFactory {
|
||||
|
||||
public static MavenResolverGrapeEngine create(GroovyClassLoader classLoader,
|
||||
List<RepositoryConfiguration> repositoryConfigurations,
|
||||
DependencyResolutionContext dependencyResolutionContext, boolean quiet) {
|
||||
RepositorySystem repositorySystem = createServiceLocator().getService(RepositorySystem.class);
|
||||
DefaultRepositorySystemSession repositorySystemSession = MavenRepositorySystemUtils.newSession();
|
||||
ServiceLoader<RepositorySystemSessionAutoConfiguration> autoConfigurations = ServiceLoader
|
||||
.load(RepositorySystemSessionAutoConfiguration.class);
|
||||
for (RepositorySystemSessionAutoConfiguration autoConfiguration : autoConfigurations) {
|
||||
autoConfiguration.apply(repositorySystemSession, repositorySystem);
|
||||
}
|
||||
new DefaultRepositorySystemSessionAutoConfiguration().apply(repositorySystemSession, repositorySystem);
|
||||
return new MavenResolverGrapeEngine(classLoader, repositorySystem, repositorySystemSession,
|
||||
createRepositories(repositoryConfigurations), dependencyResolutionContext, quiet);
|
||||
}
|
||||
|
||||
private static ServiceLocator createServiceLocator() {
|
||||
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
|
||||
locator.addService(RepositorySystem.class, DefaultRepositorySystem.class);
|
||||
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
|
||||
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
|
||||
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
|
||||
return locator;
|
||||
}
|
||||
|
||||
private static List<RemoteRepository> createRepositories(List<RepositoryConfiguration> repositoryConfigurations) {
|
||||
List<RemoteRepository> repositories = new ArrayList<>(repositoryConfigurations.size());
|
||||
for (RepositoryConfiguration repositoryConfiguration : repositoryConfigurations) {
|
||||
RemoteRepository.Builder builder = new RemoteRepository.Builder(repositoryConfiguration.getName(),
|
||||
"default", repositoryConfiguration.getUri().toASCIIString());
|
||||
if (!repositoryConfiguration.getSnapshotsEnabled()) {
|
||||
builder.setSnapshotPolicy(new RepositoryPolicy(false, RepositoryPolicy.UPDATE_POLICY_NEVER,
|
||||
RepositoryPolicy.CHECKSUM_POLICY_IGNORE));
|
||||
}
|
||||
repositories.add(builder.build());
|
||||
}
|
||||
return repositories;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -20,8 +20,8 @@ import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||
import org.eclipse.aether.RepositorySystem;
|
||||
|
||||
/**
|
||||
* Strategy that can be used to apply some auto-configuration during the installation of
|
||||
* an {@link AetherGrapeEngine}.
|
||||
* Strategy that can be used to apply some auto-configuration during the installation of a
|
||||
* {@link MavenResolverGrapeEngine}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.0.0
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -26,6 +26,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import groovy.grape.GrapeEngine;
|
||||
import groovy.lang.GroovyClassLoader;
|
||||
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||
import org.eclipse.aether.repository.Authentication;
|
||||
@ -43,7 +44,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class AetherGrapeEngineTests {
|
||||
class MavenResolverGrapeEngineTests {
|
||||
|
||||
private final GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
|
||||
|
||||
@ -53,14 +54,14 @@ class AetherGrapeEngineTests {
|
||||
private final RepositoryConfiguration springSnapshot = new RepositoryConfiguration("spring-snapshot",
|
||||
URI.create("https://repo.spring.io/snapshot"), true);
|
||||
|
||||
private AetherGrapeEngine createGrapeEngine(RepositoryConfiguration... additionalRepositories) {
|
||||
private GrapeEngine createGrapeEngine(RepositoryConfiguration... additionalRepositories) {
|
||||
List<RepositoryConfiguration> repositoryConfigurations = new ArrayList<>();
|
||||
repositoryConfigurations
|
||||
.add(new RepositoryConfiguration("central", URI.create("https://repo1.maven.org/maven2"), false));
|
||||
repositoryConfigurations.addAll(Arrays.asList(additionalRepositories));
|
||||
DependencyResolutionContext dependencyResolutionContext = new DependencyResolutionContext();
|
||||
dependencyResolutionContext.addDependencyManagement(new SpringBootDependenciesDependencyManagement());
|
||||
return AetherGrapeEngineFactory.create(this.groovyClassLoader, repositoryConfigurations,
|
||||
return MavenResolverGrapeEngineFactory.create(this.groovyClassLoader, repositoryConfigurations,
|
||||
dependencyResolutionContext, false);
|
||||
}
|
||||
|
||||
@ -75,7 +76,7 @@ class AetherGrapeEngineTests {
|
||||
@Test
|
||||
void proxySelector() {
|
||||
doWithCustomUserHome(() -> {
|
||||
AetherGrapeEngine grapeEngine = createGrapeEngine();
|
||||
GrapeEngine grapeEngine = createGrapeEngine();
|
||||
DefaultRepositorySystemSession session = (DefaultRepositorySystemSession) ReflectionTestUtils
|
||||
.getField(grapeEngine, "session");
|
||||
|
||||
@ -139,7 +140,7 @@ class AetherGrapeEngineTests {
|
||||
@Test
|
||||
void resolutionWithCustomResolver() {
|
||||
Map<String, Object> args = new HashMap<>();
|
||||
AetherGrapeEngine grapeEngine = createGrapeEngine();
|
||||
GrapeEngine grapeEngine = createGrapeEngine();
|
||||
grapeEngine.addResolver(createResolver("spring-releases", "https://repo.spring.io/release"));
|
||||
Map<String, Object> dependency = createDependency("io.spring.docresources", "spring-doc-resources",
|
||||
"0.1.1.RELEASE");
|
||||
@ -153,7 +154,7 @@ class AetherGrapeEngineTests {
|
||||
Map<String, Object> dependency = createDependency("org.grails", "grails-dependencies", "2.4.0");
|
||||
dependency.put("type", "foo");
|
||||
dependency.put("ext", "bar");
|
||||
AetherGrapeEngine grapeEngine = createGrapeEngine();
|
||||
GrapeEngine grapeEngine = createGrapeEngine();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> grapeEngine.grab(Collections.emptyMap(), dependency));
|
||||
}
|
||||
|
||||
@ -196,7 +197,7 @@ class AetherGrapeEngineTests {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<RemoteRepository> getRepositories() {
|
||||
AetherGrapeEngine grapeEngine = createGrapeEngine();
|
||||
GrapeEngine grapeEngine = createGrapeEngine();
|
||||
return (List<RemoteRepository>) ReflectionTestUtils.getField(grapeEngine, "repositories");
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
[[cli.maven-setting]]
|
||||
== Configuring the CLI with settings.xml
|
||||
The Spring Boot CLI uses Aether, Maven's dependency resolution engine, to resolve dependencies.
|
||||
The CLI makes use of the Maven configuration found in `~/.m2/settings.xml` to configure Aether.
|
||||
The Spring Boot CLI uses Maven Resolver, Maven's dependency resolution engine, to resolve dependencies.
|
||||
The CLI makes use of the Maven configuration found in `~/.m2/settings.xml` to configure Maven Resolver.
|
||||
The following configuration settings are honored by the CLI:
|
||||
|
||||
* Offline
|
||||
|
Loading…
Reference in New Issue
Block a user