Skip to content

Commit a58e4cb

Browse files
committed
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.
1 parent 2e81b1d commit a58e4cb

File tree

13 files changed

+437
-84
lines changed

13 files changed

+437
-84
lines changed

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
<module>spring-boot-actuator</module>
3838
<module>spring-boot-starters</module>
3939
<module>spring-boot-cli</module>
40+
<module>spring-boot-maven-settings</module>
4041
</modules>
4142
</profile>
4243
<profile>

spring-boot-cli/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
<type>pom</type>
3737
<scope>import</scope>
3838
</dependency>
39+
<dependency>
40+
<groupId>${project.groupId}</groupId>
41+
<artifactId>spring-boot-maven-settings</artifactId>
42+
<version>${project.version}</version>
43+
</dependency>
3944
<dependency>
4045
<groupId>org.codehaus.groovy</groupId>
4146
<artifactId>groovy-xml</artifactId>

spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.File;
2323
import java.io.IOException;
2424
import java.lang.reflect.Field;
25+
import java.net.URL;
2526
import java.util.ArrayList;
2627
import java.util.Arrays;
2728
import java.util.Collections;
@@ -42,11 +43,9 @@
4243
import org.codehaus.groovy.control.customizers.ImportCustomizer;
4344
import org.codehaus.groovy.transform.ASTTransformation;
4445
import org.codehaus.groovy.transform.ASTTransformationVisitor;
45-
import org.eclipse.aether.repository.RemoteRepository;
46-
import org.eclipse.aether.repository.RepositoryPolicy;
4746
import org.springframework.boot.cli.compiler.grape.AetherGrapeEngine;
47+
import org.springframework.boot.cli.compiler.grape.AetherGrapeEngineFactory;
4848
import org.springframework.boot.cli.compiler.grape.GrapeEngineInstaller;
49-
import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration;
5049
import org.springframework.boot.cli.compiler.transformation.DependencyAutoConfigurationTransformation;
5150
import org.springframework.boot.cli.compiler.transformation.GroovyBeansTransformation;
5251
import org.springframework.boot.cli.compiler.transformation.ResolveDependencyCoordinatesTransformation;
@@ -92,15 +91,17 @@ public GroovyCompiler(final GroovyCompilerConfiguration configuration) {
9291
this.loader = createLoader(configuration);
9392

9493
this.coordinatesResolver = new PropertiesArtifactCoordinatesResolver(this.loader);
95-
GrapeEngineInstaller.install(new AetherGrapeEngine(this.loader,
96-
createRepositories(configuration.getRepositoryConfiguration())));
94+
95+
AetherGrapeEngine grapeEngine = AetherGrapeEngineFactory.create(this.loader,
96+
configuration.getRepositoryConfiguration());
97+
98+
GrapeEngineInstaller.install(grapeEngine);
9799

98100
this.loader.getConfiguration().addCompilationCustomizers(
99101
new CompilerAutoConfigureCustomizer());
100102
if (configuration.isAutoconfigure()) {
101-
this.compilerAutoConfigurations = ServiceLoader.load(
102-
CompilerAutoConfiguration.class,
103-
GroovyCompiler.class.getClassLoader());
103+
this.compilerAutoConfigurations = ServiceLoader
104+
.load(CompilerAutoConfiguration.class);
104105
}
105106
else {
106107
this.compilerAutoConfigurations = Collections.emptySet();
@@ -122,31 +123,29 @@ public ExtendedGroovyClassLoader getLoader() {
122123

123124
private ExtendedGroovyClassLoader createLoader(
124125
GroovyCompilerConfiguration configuration) {
126+
125127
ExtendedGroovyClassLoader loader = new ExtendedGroovyClassLoader(
126128
configuration.getScope());
129+
130+
for (URL url : getExistingUrls()) {
131+
loader.addURL(url);
132+
}
133+
127134
for (String classpath : configuration.getClasspath()) {
128135
loader.addClasspath(classpath);
129136
}
137+
130138
return loader;
131139
}
132140

133-
private List<RemoteRepository> createRepositories(
134-
List<RepositoryConfiguration> repositoryConfigurations) {
135-
List<RemoteRepository> repositories = new ArrayList<RemoteRepository>(
136-
repositoryConfigurations.size());
137-
for (RepositoryConfiguration repositoryConfiguration : repositoryConfigurations) {
138-
RemoteRepository.Builder builder = new RemoteRepository.Builder(
139-
repositoryConfiguration.getName(), "default", repositoryConfiguration
140-
.getUri().toASCIIString());
141-
142-
if (!repositoryConfiguration.getSnapshotsEnabled()) {
143-
builder.setSnapshotPolicy(new RepositoryPolicy(false,
144-
RepositoryPolicy.UPDATE_POLICY_NEVER,
145-
RepositoryPolicy.CHECKSUM_POLICY_IGNORE));
146-
}
147-
repositories.add(builder.build());
141+
private URL[] getExistingUrls() {
142+
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
143+
if (tccl instanceof ExtendedGroovyClassLoader) {
144+
return ((ExtendedGroovyClassLoader) tccl).getURLs();
145+
}
146+
else {
147+
return new URL[0];
148148
}
149-
return repositories;
150149
}
151150

152151
public void addCompilationCustomizers(CompilationCustomizer... customizers) {

spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/AetherGrapeEngine.java

Lines changed: 8 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -29,34 +29,20 @@
2929
import java.util.List;
3030
import java.util.Map;
3131

32-
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
3332
import org.eclipse.aether.DefaultRepositorySystemSession;
3433
import org.eclipse.aether.RepositorySystem;
35-
import org.eclipse.aether.RepositorySystemSession;
3634
import org.eclipse.aether.artifact.Artifact;
3735
import org.eclipse.aether.artifact.DefaultArtifact;
3836
import org.eclipse.aether.collection.CollectRequest;
39-
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
4037
import org.eclipse.aether.graph.Dependency;
4138
import org.eclipse.aether.graph.Exclusion;
42-
import org.eclipse.aether.impl.DefaultServiceLocator;
43-
import org.eclipse.aether.internal.impl.DefaultRepositorySystem;
44-
import org.eclipse.aether.repository.LocalRepository;
45-
import org.eclipse.aether.repository.LocalRepositoryManager;
46-
import org.eclipse.aether.repository.ProxySelector;
4739
import org.eclipse.aether.repository.RemoteRepository;
4840
import org.eclipse.aether.resolution.ArtifactResolutionException;
4941
import org.eclipse.aether.resolution.ArtifactResult;
5042
import org.eclipse.aether.resolution.DependencyRequest;
5143
import org.eclipse.aether.resolution.DependencyResult;
52-
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
53-
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
54-
import org.eclipse.aether.spi.locator.ServiceLocator;
55-
import org.eclipse.aether.transport.file.FileTransporterFactory;
56-
import org.eclipse.aether.transport.http.HttpTransporterFactory;
5744
import org.eclipse.aether.util.artifact.JavaScopes;
5845
import org.eclipse.aether.util.filter.DependencyFilterUtils;
59-
import org.springframework.util.StringUtils;
6046

6147
/**
6248
* A {@link GrapeEngine} implementation that uses <a
@@ -76,63 +62,29 @@ public class AetherGrapeEngine implements GrapeEngine {
7662

7763
private final GroovyClassLoader classLoader;
7864

79-
private final RepositorySystemSession session;
65+
private final DefaultRepositorySystemSession session;
8066

8167
private final RepositorySystem repositorySystem;
8268

8369
private final List<RemoteRepository> repositories;
8470

85-
private ProxySelector proxySelector = new JreProxySelector();
86-
8771
public AetherGrapeEngine(GroovyClassLoader classLoader,
72+
RepositorySystem repositorySystem,
73+
DefaultRepositorySystemSession repositorySystemSession,
8874
List<RemoteRepository> remoteRepositories) {
8975
this.classLoader = classLoader;
90-
this.repositorySystem = createServiceLocator().getService(RepositorySystem.class);
91-
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
92-
LocalRepository localRepository = new LocalRepository(getM2RepoDirectory());
93-
LocalRepositoryManager localRepositoryManager = this.repositorySystem
94-
.newLocalRepositoryManager(session, localRepository);
95-
session.setLocalRepositoryManager(localRepositoryManager);
96-
session.setProxySelector(this.proxySelector);
97-
this.session = session;
76+
this.repositorySystem = repositorySystem;
77+
this.session = repositorySystemSession;
78+
9879
this.repositories = new ArrayList<RemoteRepository>();
9980
List<RemoteRepository> remotes = new ArrayList<RemoteRepository>(
10081
remoteRepositories);
10182
Collections.reverse(remotes); // priority is reversed in addRepository
10283
for (RemoteRepository repository : remotes) {
10384
addRepository(repository);
10485
}
105-
this.progressReporter = getProgressReporter(session);
106-
}
10786

108-
private ServiceLocator createServiceLocator() {
109-
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
110-
locator.addService(RepositorySystem.class, DefaultRepositorySystem.class);
111-
locator.addService(RepositoryConnectorFactory.class,
112-
BasicRepositoryConnectorFactory.class);
113-
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
114-
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
115-
return locator;
116-
}
117-
118-
private File getM2RepoDirectory() {
119-
return new File(getM2HomeDirectory(), "repository");
120-
}
121-
122-
private File getM2HomeDirectory() {
123-
String grapeRoot = System.getProperty("grape.root");
124-
if (StringUtils.hasLength(grapeRoot)) {
125-
return new File(grapeRoot);
126-
}
127-
return getDefaultM2HomeDirectory();
128-
}
129-
130-
private File getDefaultM2HomeDirectory() {
131-
String mavenRoot = System.getProperty("maven.home");
132-
if (StringUtils.hasLength(mavenRoot)) {
133-
return new File(mavenRoot);
134-
}
135-
return new File(System.getProperty("user.home"), ".m2");
87+
this.progressReporter = getProgressReporter(this.session);
13688
}
13789

13890
private ProgressReporter getProgressReporter(DefaultRepositorySystemSession session) {
@@ -268,7 +220,7 @@ protected void addRepository(RemoteRepository repository) {
268220
}
269221
if (repository.getProxy() == null) {
270222
RemoteRepository.Builder builder = new RemoteRepository.Builder(repository);
271-
builder.setProxy(this.proxySelector.getProxy(repository));
223+
builder.setProxy(this.session.getProxySelector().getProxy(repository));
272224
repository = builder.build();
273225
}
274226
this.repositories.add(0, repository);
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2012-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.cli.compiler.grape;
18+
19+
import groovy.lang.GroovyClassLoader;
20+
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
import java.util.ServiceLoader;
24+
25+
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
26+
import org.eclipse.aether.DefaultRepositorySystemSession;
27+
import org.eclipse.aether.RepositorySystem;
28+
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
29+
import org.eclipse.aether.impl.DefaultServiceLocator;
30+
import org.eclipse.aether.internal.impl.DefaultRepositorySystem;
31+
import org.eclipse.aether.repository.RemoteRepository;
32+
import org.eclipse.aether.repository.RepositoryPolicy;
33+
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
34+
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
35+
import org.eclipse.aether.spi.locator.ServiceLocator;
36+
import org.eclipse.aether.transport.file.FileTransporterFactory;
37+
import org.eclipse.aether.transport.http.HttpTransporterFactory;
38+
39+
/**
40+
* Utility class to create a pre-configured {@link AetherGrapeEngine}.
41+
*
42+
* @author Andy Wilkinson
43+
*/
44+
public abstract class AetherGrapeEngineFactory {
45+
46+
public static AetherGrapeEngine create(GroovyClassLoader classLoader,
47+
List<RepositoryConfiguration> repositoryConfigurations) {
48+
49+
RepositorySystem repositorySystem = createServiceLocator().getService(
50+
RepositorySystem.class);
51+
52+
DefaultRepositorySystemSession repositorySystemSession = MavenRepositorySystemUtils
53+
.newSession();
54+
55+
ServiceLoader<RepositorySystemSessionAutoConfiguration> autoConfigurations = ServiceLoader
56+
.load(RepositorySystemSessionAutoConfiguration.class);
57+
58+
for (RepositorySystemSessionAutoConfiguration autoConfiguration : autoConfigurations) {
59+
autoConfiguration.apply(repositorySystemSession, repositorySystem);
60+
}
61+
62+
new DefaultRepositorySystemSessionAutoConfiguration().apply(
63+
repositorySystemSession, repositorySystem);
64+
65+
return new AetherGrapeEngine(classLoader, repositorySystem,
66+
repositorySystemSession, createRepositories(repositoryConfigurations));
67+
}
68+
69+
private static ServiceLocator createServiceLocator() {
70+
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
71+
locator.addService(RepositorySystem.class, DefaultRepositorySystem.class);
72+
locator.addService(RepositoryConnectorFactory.class,
73+
BasicRepositoryConnectorFactory.class);
74+
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
75+
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
76+
return locator;
77+
}
78+
79+
private static List<RemoteRepository> createRepositories(
80+
List<RepositoryConfiguration> repositoryConfigurations) {
81+
List<RemoteRepository> repositories = new ArrayList<RemoteRepository>(
82+
repositoryConfigurations.size());
83+
for (RepositoryConfiguration repositoryConfiguration : repositoryConfigurations) {
84+
RemoteRepository.Builder builder = new RemoteRepository.Builder(
85+
repositoryConfiguration.getName(), "default", repositoryConfiguration
86+
.getUri().toASCIIString());
87+
88+
if (!repositoryConfiguration.getSnapshotsEnabled()) {
89+
builder.setSnapshotPolicy(new RepositoryPolicy(false,
90+
RepositoryPolicy.UPDATE_POLICY_NEVER,
91+
RepositoryPolicy.CHECKSUM_POLICY_IGNORE));
92+
}
93+
repositories.add(builder.build());
94+
}
95+
return repositories;
96+
}
97+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2012-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.cli.compiler.grape;
18+
19+
import java.io.File;
20+
21+
import org.eclipse.aether.DefaultRepositorySystemSession;
22+
import org.eclipse.aether.RepositorySystem;
23+
import org.eclipse.aether.repository.LocalRepository;
24+
import org.eclipse.aether.repository.LocalRepositoryManager;
25+
import org.springframework.util.StringUtils;
26+
27+
/**
28+
* A {@link RepositorySystemSessionAutoConfiguration} that, in the absence of any
29+
* configuration, applies sensible defaults.
30+
*
31+
* @author Andy Wilkinson
32+
*/
33+
public class DefaultRepositorySystemSessionAutoConfiguration implements
34+
RepositorySystemSessionAutoConfiguration {
35+
36+
@Override
37+
public void apply(DefaultRepositorySystemSession session,
38+
RepositorySystem repositorySystem) {
39+
40+
if (session.getLocalRepositoryManager() == null) {
41+
LocalRepository localRepository = new LocalRepository(getM2RepoDirectory());
42+
LocalRepositoryManager localRepositoryManager = repositorySystem
43+
.newLocalRepositoryManager(session, localRepository);
44+
session.setLocalRepositoryManager(localRepositoryManager);
45+
}
46+
47+
if (session.getProxySelector() == null) {
48+
session.setProxySelector(new JreProxySelector());
49+
}
50+
}
51+
52+
private File getM2RepoDirectory() {
53+
return new File(getM2HomeDirectory(), "repository");
54+
}
55+
56+
private File getM2HomeDirectory() {
57+
String grapeRoot = System.getProperty("grape.root");
58+
if (StringUtils.hasLength(grapeRoot)) {
59+
return new File(grapeRoot);
60+
}
61+
return getDefaultM2HomeDirectory();
62+
}
63+
64+
private File getDefaultM2HomeDirectory() {
65+
String mavenRoot = System.getProperty("maven.home");
66+
if (StringUtils.hasLength(mavenRoot)) {
67+
return new File(mavenRoot);
68+
}
69+
return new File(System.getProperty("user.home"), ".m2");
70+
}
71+
}

0 commit comments

Comments
 (0)