Skip to content

Commit 07e855b

Browse files
committed
Build: Shadow x-pack:protocol into x-pack:plugin:core (#32240)
This bundles the x-pack:protocol project into the x-pack:plugin:core project because we'd like folks to consider it an implementation detail of our build rather than a separate artifact to be managed and depended on. It is now bundled into both x-pack:plugin:core and client:rest-high-level. To make this work I had to fix a few things. Firstly, I had to make PluginBuildPlugin work with the shadow plugin. In that case we have to bundle only the `shadow` dependencies and the shadow jar. Secondly, every reference to x-pack:plugin:core has to use the `shadow` configuration. Without that the reference is missing all of the un-shadowed dependencies. I tried to make it so that applying the shadow plugin automatically redefines the `default` configuration to mirror the `shadow` configuration which would allow us to use bare project references to the x-pack:plugin:core project but I couldn't make it work. It'd *look* like it works but then fail for transitive dependencies anyway. I think it is still a good thing to do but I don't have the willpower to do it now. Finally, I had to fix an issue where Eclipse and IntelliJ didn't properly reference shadowed transitive dependencies. Neither IDE supports shadowing natively so they have to reference the shadowed projects. We fix this by detecting `shadow` dependencies when in "Intellij mode" or "Eclipse mode" and adding `runtime` dependencies to the same target. This convinces IntelliJ and Eclipse to play nice.
1 parent 1e6fa9a commit 07e855b

File tree

50 files changed

+148
-85
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+148
-85
lines changed

CONTRIBUTING.md

+36-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ If your changes affect only the documentation, run:
180180
```sh
181181
./gradlew -p docs check
182182
```
183-
For more information about testing code examples in the documentation, see
183+
For more information about testing code examples in the documentation, see
184184
https://github.com/elastic/elasticsearch/blob/master/docs/README.asciidoc
185185

186186
### Project layout
@@ -271,6 +271,39 @@ the `qa` subdirectory functions just like the top level `qa` subdirectory. The
271271
Elasticsearch process. The `transport-client` subdirectory contains extensions
272272
to Elasticsearch's standard transport client to work properly with x-pack.
273273

274+
### Gradle Build
275+
276+
We use Gradle to build Elasticsearch because it is flexible enough to not only
277+
build and package Elasticsearch, but also orchestrate all of the ways that we
278+
have to test Elasticsearch.
279+
280+
#### Configurations
281+
282+
Gradle organizes dependencies and build artifacts into "configurations" and
283+
allows you to use these configurations arbitrarilly. Here are some of the most
284+
common configurations in our build and how we use them:
285+
286+
<dl>
287+
<dt>`compile`</dt><dd>Code that is on the classpath at both compile and
288+
runtime. If the [`shadow`][shadow-plugin] plugin is applied to the project then
289+
this code is bundled into the jar produced by the project.</dd>
290+
<dt>`runtime`</dt><dd>Code that is not on the classpath at compile time but is
291+
on the classpath at runtime. We mostly use this configuration to make sure that
292+
we do not accidentally compile against dependencies of our dependencies also
293+
known as "transitive" dependencies".</dd>
294+
<dt>`compileOnly`</dt><dd>Code that is on the classpath at comile time but that
295+
should not be shipped with the project because it is "provided" by the runtime
296+
somehow. Elasticsearch plugins use this configuration to include dependencies
297+
that are bundled with Elasticsearch's server.</dd>
298+
<dt>`shadow`</dt><dd>Only available in projects with the shadow plugin. Code
299+
that is on the classpath at both compile and runtime but it *not* bundled into
300+
the jar produced by the project. If you depend on a project with the `shadow`
301+
plugin then you need to depend on this configuration because it will bring
302+
along all of the dependencies you need at runtime.</dd>
303+
<dt>`testCompile`</dt><dd>Code that is on the classpath for compiling tests
304+
that are part of this project but not production code. The canonical example
305+
of this is `junit`.</dd>
306+
</dl>
274307

275308
Contributing as part of a class
276309
-------------------------------
@@ -300,3 +333,5 @@ especially when they are unlikely to become long time contributors.
300333
Finally, we require that you run `./gradlew check` before submitting a
301334
non-documentation contribution. This is mentioned above, but it is worth
302335
repeating in this section because it has come up in this context.
336+
337+
[shadow-plugin]: https://github.com/johnrengelman/shadow

build.gradle

+25
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,31 @@ allprojects {
510510
tasks.eclipse.dependsOn(cleanEclipse, copyEclipseSettings)
511511
}
512512

513+
allprojects {
514+
/*
515+
* IntelliJ and Eclipse don't know about the shadow plugin so when we're
516+
* in "IntelliJ mode" or "Eclipse mode" add "runtime" dependencies
517+
* eveywhere where we see a "shadow" dependency which will cause them to
518+
* reference shadowed projects directly rather than rely on the shadowing
519+
* to include them. This is the correct thing for it to do because it
520+
* doesn't run the jar shadowing at all. This isn't needed for the project
521+
* itself because the IDE configuration is done by SourceSets but it is
522+
* *is* needed for projects that depends on the project doing the shadowing.
523+
* Without this they won't properly depend on the shadowed project.
524+
*/
525+
if (isEclipse || isIdea) {
526+
configurations.all { Configuration configuration ->
527+
dependencies.all { Dependency dep ->
528+
if (dep instanceof ProjectDependency) {
529+
if (dep.getTargetConfiguration() == 'shadow') {
530+
configuration.dependencies.add(project.dependencies.project(path: dep.dependencyProject.path, configuration: 'runtime'))
531+
}
532+
}
533+
}
534+
}
535+
}
536+
}
537+
513538
// we need to add the same --debug-jvm option as
514539
// the real RunTask has, so we can pass it through
515540
class Run extends DefaultTask {

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

+12
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ class BuildPlugin implements Plugin<Project> {
391391
project.configurations.compile.dependencies.all(disableTransitiveDeps)
392392
project.configurations.testCompile.dependencies.all(disableTransitiveDeps)
393393
project.configurations.compileOnly.dependencies.all(disableTransitiveDeps)
394+
project.plugins.withType(ShadowPlugin).whenPluginAdded {
395+
project.configurations.shadow.dependencies.all(disableTransitiveDeps)
396+
}
394397
}
395398

396399
/** Adds repositories used by ES dependencies */
@@ -883,11 +886,20 @@ class BuildPlugin implements Plugin<Project> {
883886
project.dependencyLicenses.dependencies = project.configurations.runtime.fileCollection {
884887
it.group.startsWith('org.elasticsearch') == false
885888
} - project.configurations.compileOnly
889+
project.plugins.withType(ShadowPlugin).whenPluginAdded {
890+
project.dependencyLicenses.dependencies += project.configurations.shadow.fileCollection {
891+
it.group.startsWith('org.elasticsearch') == false
892+
}
893+
}
886894
}
887895

888896
private static configureDependenciesInfo(Project project) {
889897
Task deps = project.tasks.create("dependenciesInfo", DependenciesInfoTask.class)
890898
deps.runtimeConfiguration = project.configurations.runtime
899+
project.plugins.withType(ShadowPlugin).whenPluginAdded {
900+
deps.runtimeConfiguration = project.configurations.create('infoDeps')
901+
deps.runtimeConfiguration.extendsFrom(project.configurations.runtime, project.configurations.shadow)
902+
}
891903
deps.compileOnlyConfiguration = project.configurations.compileOnly
892904
project.afterEvaluate {
893905
deps.mappings = project.dependencyLicenses.mappings

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

+7-14
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,6 @@ public class PluginBuildPlugin extends BuildPlugin {
4848
@Override
4949
public void apply(Project project) {
5050
super.apply(project)
51-
project.plugins.withType(ShadowPlugin).whenPluginAdded {
52-
/*
53-
* We've not tested these plugins together and we're fairly sure
54-
* they aren't going to work properly as is *and* we're not really
55-
* sure *why* you'd want to shade stuff in plugins. So we throw an
56-
* exception here to make you come and read this comment. If you
57-
* have a need for shadow while building plugins then know that you
58-
* are probably going to have to fight with gradle for a while....
59-
*/
60-
throw new InvalidUserDataException('elasticsearch.esplugin is not '
61-
+ 'compatible with com.github.johnrengelman.shadow');
62-
}
6351
configureDependencies(project)
6452
// this afterEvaluate must happen before the afterEvaluate added by integTest creation,
6553
// so that the file name resolution for installing the plugin will be setup
@@ -151,8 +139,13 @@ public class PluginBuildPlugin extends BuildPlugin {
151139
include(buildProperties.descriptorOutput.name)
152140
}
153141
from pluginMetadata // metadata (eg custom security policy)
154-
from project.jar // this plugin's jar
155-
from project.configurations.runtime - project.configurations.compileOnly // the dep jars
142+
/*
143+
* If the plugin is using the shadow plugin then we need to bundle
144+
* "shadow" things rather than the default jar and dependencies so
145+
* we don't hit jar hell.
146+
*/
147+
from { project.plugins.hasPlugin(ShadowPlugin) ? project.shadowJar : project.jar }
148+
from { project.plugins.hasPlugin(ShadowPlugin) ? project.configurations.shadow : project.configurations.runtime - project.configurations.compileOnly }
156149
// extra files for the plugin to go into the zip
157150
from('src/main/packaging') // TODO: move all config/bin/_size/etc into packaging
158151
from('src/main') {

x-pack/docs/build.gradle

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ buildRestTests.expectedUnconvertedCandidates = [
3030
]
3131

3232
dependencies {
33-
testCompile project(path: xpackModule('core'), configuration: 'runtime')
33+
testCompile project(path: xpackModule('core'), configuration: 'shadow')
3434
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
3535
testCompile project(path: xpackProject('plugin').path, configuration: 'testArtifacts')
3636
}
@@ -265,7 +265,7 @@ setups['farequote_index'] = '''
265265
airline:
266266
type: keyword
267267
doc_count:
268-
type: integer
268+
type: integer
269269
'''
270270
setups['farequote_data'] = setups['farequote_index'] + '''
271271
- do:
@@ -278,7 +278,7 @@ setups['farequote_data'] = setups['farequote_index'] + '''
278278
{"airline":"JZA","responsetime":990.4628,"time":"2016-02-07T00:00:00+0000", "doc_count": 5}
279279
{"index": {"_id":"2"}}
280280
{"airline":"JBU","responsetime":877.5927,"time":"2016-02-07T00:00:00+0000", "doc_count": 23}
281-
{"index": {"_id":"3"}}
281+
{"index": {"_id":"3"}}
282282
{"airline":"KLM","responsetime":1355.4812,"time":"2016-02-07T00:00:00+0000", "doc_count": 42}
283283
'''
284284
setups['farequote_job'] = setups['farequote_data'] + '''
@@ -310,7 +310,7 @@ setups['farequote_datafeed'] = setups['farequote_job'] + '''
310310
"job_id":"farequote",
311311
"indexes":"farequote"
312312
}
313-
'''
313+
'''
314314
setups['server_metrics_index'] = '''
315315
- do:
316316
indices.create:

x-pack/license-tools/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
apply plugin: 'elasticsearch.build'
22

33
dependencies {
4-
compile project(xpackModule('core'))
4+
compile project(path: xpackModule('core'), configuration: 'shadow')
55
compile "org.elasticsearch:elasticsearch:${version}"
66
testCompile "org.elasticsearch.test:framework:${version}"
77
}
@@ -17,7 +17,7 @@ task buildZip(type: Zip, dependsOn: jar) {
1717
into(parentDir + '/lib') {
1818
from jar
1919
from configurations.runtime
20-
}
20+
}
2121
into(parentDir + '/bin') {
2222
from 'bin'
2323
}

x-pack/plugin/core/build.gradle

+13-11
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import java.nio.file.StandardCopyOption
88
apply plugin: 'elasticsearch.esplugin'
99
apply plugin: 'nebula.maven-base-publish'
1010
apply plugin: 'nebula.maven-scm'
11+
apply plugin: 'com.github.johnrengelman.shadow'
1112

1213
archivesBaseName = 'x-pack-core'
1314

@@ -28,19 +29,19 @@ dependencyLicenses {
2829
dependencies {
2930
compileOnly "org.elasticsearch:elasticsearch:${version}"
3031
compile project(':x-pack:protocol')
31-
compile "org.apache.httpcomponents:httpclient:${versions.httpclient}"
32-
compile "org.apache.httpcomponents:httpcore:${versions.httpcore}"
33-
compile "org.apache.httpcomponents:httpcore-nio:${versions.httpcore}"
34-
compile "org.apache.httpcomponents:httpasyncclient:${versions.httpasyncclient}"
32+
shadow "org.apache.httpcomponents:httpclient:${versions.httpclient}"
33+
shadow "org.apache.httpcomponents:httpcore:${versions.httpcore}"
34+
shadow "org.apache.httpcomponents:httpcore-nio:${versions.httpcore}"
35+
shadow "org.apache.httpcomponents:httpasyncclient:${versions.httpasyncclient}"
3536

36-
compile "commons-logging:commons-logging:${versions.commonslogging}"
37-
compile "commons-codec:commons-codec:${versions.commonscodec}"
37+
shadow "commons-logging:commons-logging:${versions.commonslogging}"
38+
shadow "commons-codec:commons-codec:${versions.commonscodec}"
3839

3940
// security deps
40-
compile 'com.unboundid:unboundid-ldapsdk:3.2.0'
41-
compile 'org.bouncycastle:bcprov-jdk15on:1.59'
42-
compile 'org.bouncycastle:bcpkix-jdk15on:1.59'
43-
compile project(path: ':modules:transport-netty4', configuration: 'runtime')
41+
shadow 'com.unboundid:unboundid-ldapsdk:3.2.0'
42+
shadow 'org.bouncycastle:bcprov-jdk15on:1.59'
43+
shadow 'org.bouncycastle:bcpkix-jdk15on:1.59'
44+
shadow project(path: ':modules:transport-netty4', configuration: 'runtime')
4445

4546
testCompile 'org.elasticsearch:securemock:1.2'
4647
testCompile "org.elasticsearch:mocksocket:${versions.mocksocket}"
@@ -110,7 +111,8 @@ test {
110111
// TODO: don't publish test artifacts just to run messy tests, fix the tests!
111112
// https://github.com/elastic/x-plugins/issues/724
112113
configurations {
113-
testArtifacts.extendsFrom testRuntime
114+
testArtifacts.extendsFrom(testRuntime, shadow)
115+
testArtifacts.exclude(group: project(':x-pack:protocol').group, module: project(':x-pack:protocol').name)
114116
}
115117
task testJar(type: Jar) {
116118
appendix 'test'

x-pack/plugin/deprecation/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ archivesBaseName = 'x-pack-deprecation'
1212
compileTestJava.options.compilerArgs << "-Xlint:-deprecation,-rawtypes,-serial,-try,-unchecked"
1313

1414
dependencies {
15-
compileOnly "org.elasticsearch.plugin:x-pack-core:${version}"
15+
compileOnly project(path: xpackModule('core'), configuration: 'shadow')
1616
}
1717

1818
run {

x-pack/plugin/graph/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ esplugin {
1010
archivesBaseName = 'x-pack-graph'
1111

1212
dependencies {
13-
compileOnly "org.elasticsearch.plugin:x-pack-core:${version}"
13+
compileOnly project(path: xpackModule('core'), configuration: 'shadow')
1414
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
1515
}
1616

x-pack/plugin/logstash/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ esplugin {
1010
archivesBaseName = 'x-pack-logstash'
1111

1212
dependencies {
13-
compileOnly "org.elasticsearch.plugin:x-pack-core:${version}"
13+
compileOnly project(path: xpackModule('core'), configuration: 'shadow')
1414
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
1515

1616
}

x-pack/plugin/ml/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ compileJava.options.compilerArgs << "-Xlint:-deprecation,-rawtypes,-serial,-try,
4040
compileTestJava.options.compilerArgs << "-Xlint:-deprecation,-rawtypes,-serial,-try,-unchecked"
4141

4242
dependencies {
43-
compileOnly "org.elasticsearch.plugin:x-pack-core:${version}"
43+
compileOnly project(path: xpackModule('core'), configuration: 'shadow')
4444
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
4545
// This should not be here
4646
testCompile project(path: xpackModule('security'), configuration: 'testArtifacts')

x-pack/plugin/monitoring/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ esplugin {
1313
archivesBaseName = 'x-pack-monitoring'
1414

1515
dependencies {
16-
compileOnly "org.elasticsearch.plugin:x-pack-core:${version}"
16+
compileOnly project(path: xpackModule('core'), configuration: 'shadow')
1717
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
1818

1919
// monitoring deps
@@ -66,7 +66,7 @@ task internalClusterTest(type: RandomizedTestingTask,
6666
include '**/*IT.class'
6767
systemProperty 'es.set.netty.runtime.available.processors', 'false'
6868
}
69-
check.dependsOn internalClusterTest
69+
check.dependsOn internalClusterTest
7070
internalClusterTest.mustRunAfter test
7171

7272
// also add an "alias" task to make typing on the command line easier task icTest {

x-pack/plugin/rollup/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ compileTestJava.options.compilerArgs << "-Xlint:-rawtypes"
1616
dependencies {
1717
compileOnly "org.elasticsearch:elasticsearch:${version}"
1818

19-
compileOnly "org.elasticsearch.plugin:x-pack-core:${version}"
19+
compileOnly project(path: xpackModule('core'), configuration: 'shadow')
2020
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
2121
}
2222

x-pack/plugin/security/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ esplugin {
1212
archivesBaseName = 'x-pack-security'
1313

1414
dependencies {
15-
compileOnly "org.elasticsearch.plugin:x-pack-core:${version}"
15+
compileOnly project(path: xpackModule('core'), configuration: 'shadow')
1616
compileOnly project(path: ':modules:transport-netty4', configuration: 'runtime')
1717

1818
testCompile project(path: xpackModule('monitoring'))

x-pack/plugin/sql/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ archivesBaseName = 'x-pack-sql'
1919
integTest.enabled = false
2020

2121
dependencies {
22-
compileOnly "org.elasticsearch.plugin:x-pack-core:${version}"
22+
compileOnly project(path: xpackModule('core'), configuration: 'shadow')
2323
compileOnly(project(':modules:lang-painless')) {
2424
// exclude ASM to not affect featureAware task on Java 10+
2525
exclude group: "org.ow2.asm"

x-pack/plugin/upgrade/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ esplugin {
1414
archivesBaseName = 'x-pack-upgrade'
1515

1616
dependencies {
17-
compileOnly "org.elasticsearch.plugin:x-pack-core:${version}"
17+
compileOnly project(path: xpackModule('core'), configuration: 'shadow')
1818
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
1919
testCompile project(path: xpackModule('watcher'), configuration: 'runtime')
2020
}
@@ -40,7 +40,7 @@ task internalClusterTest(type: RandomizedTestingTask,
4040
include '**/*IT.class'
4141
systemProperty 'es.set.netty.runtime.available.processors', 'false'
4242
}
43-
check.dependsOn internalClusterTest
43+
check.dependsOn internalClusterTest
4444
internalClusterTest.mustRunAfter test
4545

4646
// also add an "alias" task to make typing on the command line easier

x-pack/plugin/watcher/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ dependencyLicenses {
2525
dependencies {
2626
compileOnly "org.elasticsearch:elasticsearch:${version}"
2727

28-
compileOnly "org.elasticsearch.plugin:x-pack-core:${version}"
28+
compileOnly project(path: xpackModule('core'), configuration: 'shadow')
2929
compileOnly project(path: ':modules:transport-netty4', configuration: 'runtime')
3030

3131
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')

x-pack/qa/full-cluster-restart/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ apply plugin: 'elasticsearch.build'
1111
test.enabled = false
1212

1313
dependencies {
14-
testCompile project(path: xpackModule('core'), configuration: 'runtime')
14+
testCompile project(path: xpackModule('core'), configuration: 'shadow')
1515
testCompile (project(path: xpackModule('security'), configuration: 'runtime')) {
1616
// Need to drop the guava dependency here or we get a conflict with watcher's guava dependency.
1717
// This is total #$%, but the solution is to get the SAML realm (which uses guava) out of security proper
@@ -261,7 +261,7 @@ subprojects {
261261
check.dependsOn(integTest)
262262

263263
dependencies {
264-
testCompile project(path: xpackModule('core'), configuration: 'runtime')
264+
testCompile project(path: xpackModule('core'), configuration: 'shadow')
265265
testCompile project(path: xpackModule('watcher'), configuration: 'runtime')
266266
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
267267
testCompile project(path: xpackModule('security'), configuration: 'testArtifacts')

x-pack/qa/ml-basic-multi-node/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apply plugin: 'elasticsearch.standalone-rest-test'
22
apply plugin: 'elasticsearch.rest-test'
33

44
dependencies {
5-
testCompile project(path: xpackModule('core'), configuration: 'runtime')
5+
testCompile project(path: xpackModule('core'), configuration: 'shadow')
66
testCompile project(path: xpackModule('ml'), configuration: 'runtime')
77
}
88

x-pack/qa/ml-disabled/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apply plugin: 'elasticsearch.standalone-rest-test'
22
apply plugin: 'elasticsearch.rest-test'
33

44
dependencies {
5-
testCompile project(path: xpackModule('core'), configuration: 'runtime')
5+
testCompile project(path: xpackModule('core'), configuration: 'shadow')
66
testCompile project(path: xpackModule('ml'), configuration: 'runtime')
77
}
88

0 commit comments

Comments
 (0)