-
Notifications
You must be signed in to change notification settings - Fork 24.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Build: Shadow x-pack:protocol into x-pack:plugin:core #32240
Conversation
Pinging @elastic/es-core-infra |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fine. A couple general comments:
- Can you add docs somewhere in contributing or something like that on the ability to shade and using the shadow vs compile?
- The name "shadow" for the configuration of what deps are not shaded. Is there a way to change this?
build.gradle
Outdated
@@ -516,6 +516,32 @@ allprojects { | |||
tasks.eclipse.dependsOn(cleanEclipse, copyEclipseSettings) | |||
} | |||
|
|||
allprojects { | |||
/* | |||
* IntelliJ and, ironically, Eclipse don't know about the shadow plugin so |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: It's unclear why this is "ironic". I would omit this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do. It is ironic because and eclipse is caused by a shadow.
/* | ||
* We bundle the plugin's jar file and its dependencies. We have | ||
* to wait until the project is evaluated before we know if the | ||
* plug *has* the shadow plugin. If it does we need the shadow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
plug -> project?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
++
We'd have to make a new configuration. I was weary to do that at first but I think I understand how all things hangs together well enough to do that. What do you think of the name
I'll add that before merging. |
And thanks for reviewing @rjernst! |
Includes a start of explaining gradle and gradle projects which feels sort of required before talking about configurations. Not at all finished but a start.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the advantage of using the shadow plugin as opposed to configuring the x-pack:core, high level rest and possibly other builds to simply include the class and resource files from the protocol project as in jar { from project(':x-pack:protocol').classes ; from project(':x-pack:protocol').processResources }
( or something like that ) with a compile only dependency on project(':x-pack:protocol')
to keep the IDEs happy about it could do this without leaking shadow plugin semantics across the build. It feels to me that we are throwing out too much of what the plugin does to warrant using it.
We could even generalize that by creating a configuration of our own bundled
or baked
that can have only project level dependencies that behave like mentioned above: added to the jar and as compileOnly deps. Would probably keep things simpler in the gradle side.
@@ -873,11 +876,20 @@ class BuildPlugin implements Plugin<Project> { | |||
project.dependencyLicenses.dependencies = project.configurations.runtime.fileCollection { | |||
it.group.startsWith('org.elasticsearch') == false | |||
} - project.configurations.compileOnly | |||
project.plugins.withType(ShadowPlugin).whenPluginAdded { | |||
project.dependencyLicenses.dependencies += project.configurations.shadow.fileCollection { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is new, but I think this will resolve the configuration at configuration time which is undesirable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It mimics what we do above for the runtime
configuration. I'm not arguing that it is right, just that it is in good company.
CONTRIBUTING.md
Outdated
|
||
<dl> | ||
<dt>`compile`</dt><dd>Code that is on the classpath at both compile and | ||
runtime. If the `shadow` plugin is applied to the project then this code is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might want to link to the shadow
to be 100% clear on what plugin is meant.
There are often multiple Gradle plugins doing the same thing and its easy to get confused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Linked!
* we're fine with the jar an all of the non-provided runtime | ||
* dependencies. | ||
*/ | ||
project.afterEvaluate { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from
accepts closures that run at execution time for this type of usage.
It does mean that the conditional has to move into the closure
from { project.plugins.hasPlugin(ShadowPlugin) ? project.shadowJar : project.jar }
from { project.plugins.hasPlugin(ShadowPlugin) ? project.configurations.shadow : project.configurations.compileOnly }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That works! Awesome!
I don't think it is worth re-implementing a bunch of the semantics of the shadow plugin though. We actually activate the META-INF merging across the board which is quite useful. And the jdbc driver uses relocation. So I think the shadow plugin is the right choice for us. I don't think we can get away without leaking shadow semantics out of the build because we'd end up including the bundled classes twice in dependencies which will cause jar hell to fail. I'd love to alter the I'll certainly look at your other points! |
LGTM Would be great if we could change the default configuration to shadow but we can do it in another PR as discussed. |
Thanks for reviewing @atorok and @rjernst! I have two follow up things to do after I finish backporting this:
|
I like the idea of having a |
* master: Security: revert to old way of merging automata (#32254) Networking: Fix test leaking buffer (#32296) Undo a debugging change that snuck in during the field aliases merge. Painless: Update More Methods to New Naming Scheme (#32305) [TEST] Fix assumeFalse -> assumeTrue in SSLReloadIntegTests Ingest: Support integer and long hex values in convert (#32213) Introduce fips_mode setting and associated checks (#32326) Add V_6_3_3 version constant [DOCS] Removed extraneous callout number. Rest HL client: Add put license action (#32214) Add ERR to ranking evaluation documentation (#32314) Introduce Application Privileges with support for Kibana RBAC (#32309) Build: Shadow x-pack:protocol into x-pack:plugin:core (#32240) [Kerberos] Add Kerberos authentication support (#32263) [ML] Extract persistent task methods from MlMetadata (#32319) Add Restore Snapshot High Level REST API Register ERR metric with NamedXContentRegistry (#32320) fixes broken build for third-party-tests (#32315) Allow Integ Tests to run in a FIPS-140 JVM (#31989) [DOCS] Rollup Caps API incorrectly mentions GET Jobs API (#32280) awaitsfix testRandomClusterStateUpdates [TEST] add version skip to weighted_avg tests Consistent encoder names (#29492) Add WeightedAvg metric aggregation (#31037) Switch monitoring to new style Requests (#32255) Rename ranking evaluation `quality_level` to `metric_score` (#32168) Fix a test bug around nested aggregations and field aliases. (#32287) Add new permission for JDK11 to load JAAS libraries (#32132) Silence SSL reload test that fails on JDK 11 [test] package pre-install java check (#32259) specify subdirs of lib, bin, modules in package (#32253) Switch x-pack:core to new style Requests (#32252) awaitsfix SSLConfigurationReloaderTests Painless: Clean up add methods in PainlessLookup (#32258) Fail shard if IndexShard#storeStats runs into an IOException (#32241) AwaitsFix RecoveryIT#testHistoryUUIDIsGenerated Remove unnecessary warning supressions (#32250) CCE when re-throwing "shard not available" exception in TransportShardMultiGetAction (#32185) Add new fields to monitoring template for Beats state (#32085)
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.
* elastic/6.x: Tests: Fix XPack upgrade tests (#32352) Remove invalid entry from 6.3.2 release notes Number of utilities for writing gradle integration tests (#32282) Determine the minimum gradle version based on the wrapper (#32226) Enable FIPS JVM in CI (#32330) Build: Fix jarHell error I caused by last backport Build: Shadow x-pack:protocol into x-pack:plugin:core (#32240)
I opened #32409 to rework the configuration of the shadow plugin. I think it makes it much more obvious what is going on. |
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 theshadow 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 theshadow
configuration which would allow us to use bare project referencesto 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 convincesIntelliJ and Eclipse to play nice.