Add support for configuring Aether via settings.xml
Previously, Aether's configuration was largely hard-coded making it
impossible to configure a mirror, provide credentials for accessing
a repository, etc.
This commit adds support for configuring Aether via Maven's
settings.xml file. The support is optional and must be enabled by
grabbing spring-boot-maven-settings in an init script. The Aether
instance that's used when running the application will then be
configured using settings.xml. The settings file is expected to be
found in ${user.home}/.m2/settings.xml.
The configuration of the following items is currently supported:
- Offline
- Proxies
- Mirrors
- Server authentication
- Local repository location
If the support is not enabled, settings.xml does not exist, or
settings.xml does not configure certain things then sensible defaults
are applied.
This commit is contained in:
@@ -22,6 +22,7 @@ import groovy.lang.GroovyClassLoader.ClassCollector;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -42,11 +43,9 @@ import org.codehaus.groovy.control.customizers.CompilationCustomizer;
|
||||
import org.codehaus.groovy.control.customizers.ImportCustomizer;
|
||||
import org.codehaus.groovy.transform.ASTTransformation;
|
||||
import org.codehaus.groovy.transform.ASTTransformationVisitor;
|
||||
import org.eclipse.aether.repository.RemoteRepository;
|
||||
import org.eclipse.aether.repository.RepositoryPolicy;
|
||||
import org.springframework.boot.cli.compiler.grape.AetherGrapeEngine;
|
||||
import org.springframework.boot.cli.compiler.grape.AetherGrapeEngineFactory;
|
||||
import org.springframework.boot.cli.compiler.grape.GrapeEngineInstaller;
|
||||
import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration;
|
||||
import org.springframework.boot.cli.compiler.transformation.DependencyAutoConfigurationTransformation;
|
||||
import org.springframework.boot.cli.compiler.transformation.GroovyBeansTransformation;
|
||||
import org.springframework.boot.cli.compiler.transformation.ResolveDependencyCoordinatesTransformation;
|
||||
@@ -92,15 +91,17 @@ public class GroovyCompiler {
|
||||
this.loader = createLoader(configuration);
|
||||
|
||||
this.coordinatesResolver = new PropertiesArtifactCoordinatesResolver(this.loader);
|
||||
GrapeEngineInstaller.install(new AetherGrapeEngine(this.loader,
|
||||
createRepositories(configuration.getRepositoryConfiguration())));
|
||||
|
||||
AetherGrapeEngine grapeEngine = AetherGrapeEngineFactory.create(this.loader,
|
||||
configuration.getRepositoryConfiguration());
|
||||
|
||||
GrapeEngineInstaller.install(grapeEngine);
|
||||
|
||||
this.loader.getConfiguration().addCompilationCustomizers(
|
||||
new CompilerAutoConfigureCustomizer());
|
||||
if (configuration.isAutoconfigure()) {
|
||||
this.compilerAutoConfigurations = ServiceLoader.load(
|
||||
CompilerAutoConfiguration.class,
|
||||
GroovyCompiler.class.getClassLoader());
|
||||
this.compilerAutoConfigurations = ServiceLoader
|
||||
.load(CompilerAutoConfiguration.class);
|
||||
}
|
||||
else {
|
||||
this.compilerAutoConfigurations = Collections.emptySet();
|
||||
@@ -122,31 +123,29 @@ public class GroovyCompiler {
|
||||
|
||||
private ExtendedGroovyClassLoader createLoader(
|
||||
GroovyCompilerConfiguration configuration) {
|
||||
|
||||
ExtendedGroovyClassLoader loader = new ExtendedGroovyClassLoader(
|
||||
configuration.getScope());
|
||||
|
||||
for (URL url : getExistingUrls()) {
|
||||
loader.addURL(url);
|
||||
}
|
||||
|
||||
for (String classpath : configuration.getClasspath()) {
|
||||
loader.addClasspath(classpath);
|
||||
}
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
private List<RemoteRepository> createRepositories(
|
||||
List<RepositoryConfiguration> repositoryConfigurations) {
|
||||
List<RemoteRepository> repositories = new ArrayList<RemoteRepository>(
|
||||
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());
|
||||
private URL[] getExistingUrls() {
|
||||
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
|
||||
if (tccl instanceof ExtendedGroovyClassLoader) {
|
||||
return ((ExtendedGroovyClassLoader) tccl).getURLs();
|
||||
}
|
||||
else {
|
||||
return new URL[0];
|
||||
}
|
||||
return repositories;
|
||||
}
|
||||
|
||||
public void addCompilationCustomizers(CompilationCustomizer... customizers) {
|
||||
|
||||
@@ -29,34 +29,20 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
|
||||
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||
import org.eclipse.aether.RepositorySystem;
|
||||
import org.eclipse.aether.RepositorySystemSession;
|
||||
import org.eclipse.aether.artifact.Artifact;
|
||||
import org.eclipse.aether.artifact.DefaultArtifact;
|
||||
import org.eclipse.aether.collection.CollectRequest;
|
||||
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
|
||||
import org.eclipse.aether.graph.Dependency;
|
||||
import org.eclipse.aether.graph.Exclusion;
|
||||
import org.eclipse.aether.impl.DefaultServiceLocator;
|
||||
import org.eclipse.aether.internal.impl.DefaultRepositorySystem;
|
||||
import org.eclipse.aether.repository.LocalRepository;
|
||||
import org.eclipse.aether.repository.LocalRepositoryManager;
|
||||
import org.eclipse.aether.repository.ProxySelector;
|
||||
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.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;
|
||||
import org.eclipse.aether.util.artifact.JavaScopes;
|
||||
import org.eclipse.aether.util.filter.DependencyFilterUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A {@link GrapeEngine} implementation that uses <a
|
||||
@@ -76,25 +62,20 @@ public class AetherGrapeEngine implements GrapeEngine {
|
||||
|
||||
private final GroovyClassLoader classLoader;
|
||||
|
||||
private final RepositorySystemSession session;
|
||||
private final DefaultRepositorySystemSession session;
|
||||
|
||||
private final RepositorySystem repositorySystem;
|
||||
|
||||
private final List<RemoteRepository> repositories;
|
||||
|
||||
private ProxySelector proxySelector = new JreProxySelector();
|
||||
|
||||
public AetherGrapeEngine(GroovyClassLoader classLoader,
|
||||
RepositorySystem repositorySystem,
|
||||
DefaultRepositorySystemSession repositorySystemSession,
|
||||
List<RemoteRepository> remoteRepositories) {
|
||||
this.classLoader = classLoader;
|
||||
this.repositorySystem = createServiceLocator().getService(RepositorySystem.class);
|
||||
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
|
||||
LocalRepository localRepository = new LocalRepository(getM2RepoDirectory());
|
||||
LocalRepositoryManager localRepositoryManager = this.repositorySystem
|
||||
.newLocalRepositoryManager(session, localRepository);
|
||||
session.setLocalRepositoryManager(localRepositoryManager);
|
||||
session.setProxySelector(this.proxySelector);
|
||||
this.session = session;
|
||||
this.repositorySystem = repositorySystem;
|
||||
this.session = repositorySystemSession;
|
||||
|
||||
this.repositories = new ArrayList<RemoteRepository>();
|
||||
List<RemoteRepository> remotes = new ArrayList<RemoteRepository>(
|
||||
remoteRepositories);
|
||||
@@ -102,37 +83,8 @@ public class AetherGrapeEngine implements GrapeEngine {
|
||||
for (RemoteRepository repository : remotes) {
|
||||
addRepository(repository);
|
||||
}
|
||||
this.progressReporter = getProgressReporter(session);
|
||||
}
|
||||
|
||||
private 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 File getM2RepoDirectory() {
|
||||
return new File(getM2HomeDirectory(), "repository");
|
||||
}
|
||||
|
||||
private File getM2HomeDirectory() {
|
||||
String grapeRoot = System.getProperty("grape.root");
|
||||
if (StringUtils.hasLength(grapeRoot)) {
|
||||
return new File(grapeRoot);
|
||||
}
|
||||
return getDefaultM2HomeDirectory();
|
||||
}
|
||||
|
||||
private File getDefaultM2HomeDirectory() {
|
||||
String mavenRoot = System.getProperty("maven.home");
|
||||
if (StringUtils.hasLength(mavenRoot)) {
|
||||
return new File(mavenRoot);
|
||||
}
|
||||
return new File(System.getProperty("user.home"), ".m2");
|
||||
this.progressReporter = getProgressReporter(this.session);
|
||||
}
|
||||
|
||||
private ProgressReporter getProgressReporter(DefaultRepositorySystemSession session) {
|
||||
@@ -268,7 +220,7 @@ public class AetherGrapeEngine implements GrapeEngine {
|
||||
}
|
||||
if (repository.getProxy() == null) {
|
||||
RemoteRepository.Builder builder = new RemoteRepository.Builder(repository);
|
||||
builder.setProxy(this.proxySelector.getProxy(repository));
|
||||
builder.setProxy(this.session.getProxySelector().getProxy(repository));
|
||||
repository = builder.build();
|
||||
}
|
||||
this.repositories.add(0, repository);
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.cli.compiler.grape;
|
||||
|
||||
import groovy.lang.GroovyClassLoader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
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 AetherGrapeEngine}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public abstract class AetherGrapeEngineFactory {
|
||||
|
||||
public static AetherGrapeEngine create(GroovyClassLoader classLoader,
|
||||
List<RepositoryConfiguration> repositoryConfigurations) {
|
||||
|
||||
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 AetherGrapeEngine(classLoader, repositorySystem,
|
||||
repositorySystemSession, createRepositories(repositoryConfigurations));
|
||||
}
|
||||
|
||||
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<RemoteRepository>(
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.cli.compiler.grape;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||
import org.eclipse.aether.RepositorySystem;
|
||||
import org.eclipse.aether.repository.LocalRepository;
|
||||
import org.eclipse.aether.repository.LocalRepositoryManager;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A {@link RepositorySystemSessionAutoConfiguration} that, in the absence of any
|
||||
* configuration, applies sensible defaults.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class DefaultRepositorySystemSessionAutoConfiguration implements
|
||||
RepositorySystemSessionAutoConfiguration {
|
||||
|
||||
@Override
|
||||
public void apply(DefaultRepositorySystemSession session,
|
||||
RepositorySystem repositorySystem) {
|
||||
|
||||
if (session.getLocalRepositoryManager() == null) {
|
||||
LocalRepository localRepository = new LocalRepository(getM2RepoDirectory());
|
||||
LocalRepositoryManager localRepositoryManager = repositorySystem
|
||||
.newLocalRepositoryManager(session, localRepository);
|
||||
session.setLocalRepositoryManager(localRepositoryManager);
|
||||
}
|
||||
|
||||
if (session.getProxySelector() == null) {
|
||||
session.setProxySelector(new JreProxySelector());
|
||||
}
|
||||
}
|
||||
|
||||
private File getM2RepoDirectory() {
|
||||
return new File(getM2HomeDirectory(), "repository");
|
||||
}
|
||||
|
||||
private File getM2HomeDirectory() {
|
||||
String grapeRoot = System.getProperty("grape.root");
|
||||
if (StringUtils.hasLength(grapeRoot)) {
|
||||
return new File(grapeRoot);
|
||||
}
|
||||
return getDefaultM2HomeDirectory();
|
||||
}
|
||||
|
||||
private File getDefaultM2HomeDirectory() {
|
||||
String mavenRoot = System.getProperty("maven.home");
|
||||
if (StringUtils.hasLength(mavenRoot)) {
|
||||
return new File(mavenRoot);
|
||||
}
|
||||
return new File(System.getProperty("user.home"), ".m2");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.cli.compiler.grape;
|
||||
|
||||
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}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public interface RepositorySystemSessionAutoConfiguration {
|
||||
|
||||
/**
|
||||
* Apply the configuration
|
||||
*/
|
||||
void apply(DefaultRepositorySystemSession session, RepositorySystem repositorySystem);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user