Skip to content

Commit eda3da3

Browse files
authored
Improve build configuration time (#41392)
This commit moves the expensive configuration-time calculation of Java runtime version information to runtime instead and also makes that work cacheable. This roughly equates to about a 50% reduction in project configuration time.
1 parent 5720a32 commit eda3da3

File tree

31 files changed

+1022
-649
lines changed

31 files changed

+1022
-649
lines changed

build.gradle

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import org.gradle.plugins.ide.eclipse.model.SourceFolder
3131
plugins {
3232
id 'com.gradle.build-scan' version '2.2.1'
3333
id 'base'
34+
id 'elasticsearch.global-build-info'
3435
}
3536
if (Boolean.valueOf(project.findProperty('org.elasticsearch.acceptScanTOS') ?: "false")) {
3637
buildScan {
@@ -262,7 +263,7 @@ allprojects {
262263
}
263264

264265
project.afterEvaluate {
265-
configurations.all {
266+
configurations.matching { it.canBeResolved }.all {
266267
resolutionStrategy.dependencySubstitution { DependencySubstitutions subs ->
267268
projectSubstitutions.each { k,v ->
268269
subs.substitute(subs.module(k)).with(subs.project(v))
@@ -336,7 +337,7 @@ gradle.projectsEvaluated {
336337
if (tasks.findByPath('test') != null && tasks.findByPath('integTest') != null) {
337338
integTest.mustRunAfter test
338339
}
339-
configurations.all { Configuration configuration ->
340+
configurations.matching { it.canBeResolved }.all { Configuration configuration ->
340341
dependencies.all { Dependency dep ->
341342
Project upstreamProject = dependencyToProject(dep)
342343
if (upstreamProject != null) {
@@ -617,7 +618,3 @@ allprojects {
617618
}
618619
}
619620
}
620-
621-
622-
623-

buildSrc/build.gradle

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -69,37 +69,10 @@ processResources {
6969
if (JavaVersion.current() < JavaVersion.VERSION_11) {
7070
throw new GradleException('At least Java 11 is required to build elasticsearch gradle tools')
7171
}
72-
// Gradle 4.10 does not support setting this to 11 yet
73-
targetCompatibility = "10"
74-
sourceCompatibility = "10"
75-
76-
// We have a few classes that need to be compiled for older java versions because these are used to run checks against
77-
// those
78-
sourceSets {
79-
minimumRuntime {
80-
// We only want Java here, but the Groovy doesn't configure javadoc correctly if we don't define this as groovy
81-
groovy {
82-
srcDirs = ['src/main/minimumRuntime']
83-
}
84-
}
85-
}
86-
compileMinimumRuntimeGroovy {
87-
targetCompatibility = 8
88-
sourceCompatibility = 8
89-
}
90-
dependencies {
91-
if (project.ext.has("isEclipse") == false || project.ext.isEclipse == false) {
92-
// eclipse is confused if this is set explicitly
93-
compile sourceSets.minimumRuntime.output
94-
}
95-
minimumRuntimeCompile "junit:junit:${props.getProperty('junit')}"
96-
minimumRuntimeCompile localGroovy()
97-
minimumRuntimeCompile gradleApi()
98-
}
99-
jar {
100-
from sourceSets.minimumRuntime.output
101-
}
10272

73+
// Keep compatibility with Java 8 for external users of build-tools that haven't migrated to Java 11
74+
targetCompatibility = '8'
75+
sourceCompatibility = '8'
10376

10477
/*****************************************************************************
10578
* Dependencies used by the entire build *
@@ -164,7 +137,6 @@ if (project != rootProject) {
164137
dependenciesInfo.enabled = false
165138
forbiddenApisMain.enabled = false
166139
forbiddenApisTest.enabled = false
167-
forbiddenApisMinimumRuntime.enabled = false
168140
jarHell.enabled = false
169141
thirdPartyAudit.enabled = false
170142

buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy

Lines changed: 270 additions & 467 deletions
Large diffs are not rendered by default.

buildSrc/src/main/groovy/org/elasticsearch/gradle/plugin/PluginBuildPlugin.groovy

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import org.elasticsearch.gradle.test.RestIntegTestTask
2828
import org.elasticsearch.gradle.test.RunTask
2929
import org.elasticsearch.gradle.testclusters.TestClustersPlugin
3030
import org.gradle.api.InvalidUserDataException
31+
import org.gradle.api.Plugin
3132
import org.gradle.api.Project
3233
import org.gradle.api.Task
3334
import org.gradle.api.publish.maven.MavenPublication
@@ -43,13 +44,13 @@ import java.util.regex.Pattern
4344
/**
4445
* Encapsulates build configuration for an Elasticsearch plugin.
4546
*/
46-
class PluginBuildPlugin extends BuildPlugin {
47+
class PluginBuildPlugin implements Plugin<Project> {
4748

4849
public static final String PLUGIN_EXTENSION_NAME = 'esplugin'
4950

5051
@Override
5152
void apply(Project project) {
52-
super.apply(project)
53+
project.pluginManager.apply(BuildPlugin)
5354

5455
PluginPropertiesExtension extension = project.extensions.create(PLUGIN_EXTENSION_NAME, PluginPropertiesExtension, project)
5556
configureDependencies(project)

buildSrc/src/main/groovy/org/elasticsearch/gradle/precommit/PrecommitTasks.groovy

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -118,31 +118,32 @@ class PrecommitTasks {
118118
}
119119

120120
private static Task configureThirdPartyAudit(Project project) {
121-
ThirdPartyAuditTask thirdPartyAuditTask = project.tasks.create('thirdPartyAudit', ThirdPartyAuditTask.class)
122121
ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources')
123-
thirdPartyAuditTask.configure {
124-
dependsOn(buildResources)
125-
signatureFile = buildResources.copy("forbidden/third-party-audit.txt")
126-
javaHome = project.runtimeJavaHome
127-
targetCompatibility = project.runtimeJavaVersion
122+
return project.tasks.create('thirdPartyAudit', ThirdPartyAuditTask.class) { task ->
123+
task.dependsOn(buildResources)
124+
task.signatureFile = buildResources.copy("forbidden/third-party-audit.txt")
125+
task.javaHome = project.runtimeJavaHome
126+
task.targetCompatibility.set(project.provider({ project.runtimeJavaVersion }))
128127
}
129-
return thirdPartyAuditTask
130128
}
131129

132130
private static Task configureForbiddenApisCli(Project project) {
133131
project.pluginManager.apply(ForbiddenApisPlugin)
134132
ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources')
135133
project.tasks.withType(CheckForbiddenApis) {
136134
dependsOn(buildResources)
137-
targetCompatibility = project.runtimeJavaVersion.getMajorVersion()
138-
if (project.runtimeJavaVersion > JavaVersion.VERSION_11) {
139-
doLast {
140-
project.logger.info(
141-
"Forbidden APIs does not support java version past 11. Will use the signatures from 11 for ",
142-
project.runtimeJavaVersion
143-
)
135+
doFirst {
136+
// we need to defer this configuration since we don't know the runtime java version until execution time
137+
targetCompatibility = project.runtimeJavaVersion.getMajorVersion()
138+
if (project.runtimeJavaVersion > JavaVersion.VERSION_11) {
139+
doLast {
140+
project.logger.info(
141+
"Forbidden APIs does not support java version past 11. Will use the signatures from 11 for ",
142+
project.runtimeJavaVersion
143+
)
144+
}
145+
targetCompatibility = JavaVersion.VERSION_11.getMajorVersion()
144146
}
145-
targetCompatibility = JavaVersion.VERSION_11.getMajorVersion()
146147
}
147148
bundledSignatures = [
148149
"jdk-unsafe", "jdk-deprecated", "jdk-non-portable", "jdk-system-out"

buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,6 @@ class ClusterFormationTasks {
300300
// its run after plugins have been installed, as the extra config files may belong to plugins
301301
setup = configureExtraConfigFilesTask(taskName(prefix, node, 'extraConfig'), project, setup, node)
302302

303-
// If the node runs in a FIPS 140-2 JVM, the BCFKS default keystore will be password protected
304-
if (project.inFipsJvm){
305-
node.config.systemProperties.put('javax.net.ssl.trustStorePassword', 'password')
306-
node.config.systemProperties.put('javax.net.ssl.keyStorePassword', 'password')
307-
}
308-
309303
// extra setup commands
310304
for (Map.Entry<String, Object[]> command : node.config.setupCommands.entrySet()) {
311305
// the first argument is the actual script name, relative to home
@@ -402,16 +396,17 @@ class ClusterFormationTasks {
402396
if (node.nodeVersion.major >= 7) {
403397
esConfig['indices.breaker.total.use_real_memory'] = false
404398
}
405-
for (Map.Entry<String, Object> setting : node.config.settings) {
406-
if (setting.value == null) {
407-
esConfig.remove(setting.key)
408-
} else {
409-
esConfig.put(setting.key, setting.value)
410-
}
411-
}
412399

413400
Task writeConfig = project.tasks.create(name: name, type: DefaultTask, dependsOn: setup)
414401
writeConfig.doFirst {
402+
for (Map.Entry<String, Object> setting : node.config.settings) {
403+
if (setting.value == null) {
404+
esConfig.remove(setting.key)
405+
} else {
406+
esConfig.put(setting.key, setting.value)
407+
}
408+
}
409+
415410
esConfig = configFilter.call(esConfig)
416411
File configFile = new File(node.pathConf, 'elasticsearch.yml')
417412
logger.info("Configuring ${configFile}")
@@ -732,6 +727,12 @@ class ClusterFormationTasks {
732727
}
733728
start.doLast(elasticsearchRunner)
734729
start.doFirst {
730+
// If the node runs in a FIPS 140-2 JVM, the BCFKS default keystore will be password protected
731+
if (project.inFipsJvm){
732+
node.config.systemProperties.put('javax.net.ssl.trustStorePassword', 'password')
733+
node.config.systemProperties.put('javax.net.ssl.keyStorePassword', 'password')
734+
}
735+
735736
// Configure ES JAVA OPTS - adds system properties, assertion flags, remote debug etc
736737
List<String> esJavaOpts = [node.env.get('ES_JAVA_OPTS', '')]
737738
String collectedSystemProperties = node.config.systemProperties.collect { key, value -> "-D${key}=${value}" }.join(" ")

buildSrc/src/main/groovy/org/elasticsearch/gradle/test/RestIntegTestTask.groovy

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -86,52 +86,25 @@ class RestIntegTestTask extends DefaultTask {
8686
runner.include('**/*IT.class')
8787
runner.systemProperty('tests.rest.load_packaged', 'false')
8888

89-
/*
90-
* We use lazy-evaluated strings in order to configure system properties whose value will not be known until
91-
* execution time (e.g. cluster port numbers). Adding these via the normal DSL doesn't work as these get treated
92-
* as task inputs and therefore Gradle attempts to snapshot them before/after task execution. This fails due
93-
* to the GStrings containing references to non-serializable objects.
94-
*
95-
* We bypass this by instead passing this system properties vi a CommandLineArgumentProvider. This has the added
96-
* side-effect that these properties are NOT treated as inputs, therefore they don't influence things like the
97-
* build cache key or up to date checking.
98-
*/
99-
def nonInputProperties = new CommandLineArgumentProvider() {
100-
private final Map<String, Object> systemProperties = [:]
101-
102-
void systemProperty(String key, Object value) {
103-
systemProperties.put(key, value)
104-
}
105-
106-
@Override
107-
Iterable<String> asArguments() {
108-
return systemProperties.collect { key, value ->
109-
"-D${key}=${value.toString()}".toString()
110-
}
111-
}
112-
}
113-
runner.jvmArgumentProviders.add(nonInputProperties)
114-
runner.ext.nonInputProperties = nonInputProperties
115-
11689
if (System.getProperty("tests.rest.cluster") == null) {
11790
if (System.getProperty("tests.cluster") != null || System.getProperty("tests.clustername") != null) {
11891
throw new IllegalArgumentException("tests.rest.cluster, tests.cluster, and tests.clustername must all be null or non-null")
11992
}
12093
if (usesTestclusters == true) {
12194
ElasticsearchCluster cluster = project.testClusters."${name}"
122-
nonInputProperties.systemProperty('tests.rest.cluster', "${-> cluster.allHttpSocketURI.join(",") }")
123-
nonInputProperties.systemProperty('tests.cluster', "${-> cluster.transportPortURI }")
124-
nonInputProperties.systemProperty('tests.clustername', "${-> cluster.getName() }")
95+
runner.nonInputProperties.systemProperty('tests.rest.cluster', "${-> cluster.allHttpSocketURI.join(",") }")
96+
runner.nonInputProperties.systemProperty('tests.cluster', "${-> cluster.transportPortURI }")
97+
runner.nonInputProperties.systemProperty('tests.clustername', "${-> cluster.getName() }")
12598
} else {
12699
// we pass all nodes to the rest cluster to allow the clients to round-robin between them
127100
// this is more realistic than just talking to a single node
128-
nonInputProperties.systemProperty('tests.rest.cluster', "${-> nodes.collect { it.httpUri() }.join(",")}")
129-
nonInputProperties.systemProperty('tests.config.dir', "${-> nodes[0].pathConf}")
101+
runner.nonInputProperties.systemProperty('tests.rest.cluster', "${-> nodes.collect { it.httpUri() }.join(",")}")
102+
runner.nonInputProperties.systemProperty('tests.config.dir', "${-> nodes[0].pathConf}")
130103
// TODO: our "client" qa tests currently use the rest-test plugin. instead they should have their own plugin
131104
// that sets up the test cluster and passes this transport uri instead of http uri. Until then, we pass
132105
// both as separate sysprops
133-
nonInputProperties.systemProperty('tests.cluster', "${-> nodes[0].transportUri()}")
134-
nonInputProperties.systemProperty('tests.clustername', "${-> nodes[0].clusterName}")
106+
runner.nonInputProperties.systemProperty('tests.cluster', "${-> nodes[0].transportUri()}")
107+
runner.nonInputProperties.systemProperty('tests.clustername', "${-> nodes[0].clusterName}")
135108

136109
// dump errors and warnings from cluster log on failure
137110
TaskExecutionAdapter logDumpListener = new TaskExecutionAdapter() {

buildSrc/src/main/groovy/org/elasticsearch/gradle/test/StandaloneRestTestPlugin.groovy

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@ import org.elasticsearch.gradle.ExportElasticsearchBuildResourcesTask
2727
import org.elasticsearch.gradle.VersionProperties
2828
import org.elasticsearch.gradle.precommit.PrecommitTasks
2929
import org.gradle.api.InvalidUserDataException
30+
import org.gradle.api.JavaVersion
3031
import org.gradle.api.Plugin
3132
import org.gradle.api.Project
3233
import org.gradle.api.artifacts.Configuration
34+
import org.gradle.api.plugins.ExtraPropertiesExtension
3335
import org.gradle.api.plugins.JavaBasePlugin
3436
import org.gradle.api.plugins.JavaPlugin
37+
import org.gradle.api.plugins.JavaPluginExtension
3538
import org.gradle.api.tasks.SourceSet
3639
import org.gradle.api.tasks.SourceSetContainer
3740
import org.gradle.api.tasks.compile.JavaCompile
@@ -57,10 +60,13 @@ class StandaloneRestTestPlugin implements Plugin<Project> {
5760
project.pluginManager.apply(JavaBasePlugin)
5861

5962
project.getTasks().create("buildResources", ExportElasticsearchBuildResourcesTask)
60-
BuildPlugin.globalBuildInfo(project)
6163
BuildPlugin.configureRepositories(project)
6264
BuildPlugin.configureTestTasks(project)
6365

66+
ExtraPropertiesExtension ext = project.extensions.getByType(ExtraPropertiesExtension)
67+
project.extensions.getByType(JavaPluginExtension).sourceCompatibility = ext.get('minimumRuntimeVersion') as JavaVersion
68+
project.extensions.getByType(JavaPluginExtension).targetCompatibility = ext.get('minimumRuntimeVersion') as JavaVersion
69+
6470
// only setup tests to build
6571
SourceSetContainer sourceSets = project.extensions.getByType(SourceSetContainer)
6672
SourceSet testSourceSet = sourceSets.create('test')

0 commit comments

Comments
 (0)