-
Notifications
You must be signed in to change notification settings - Fork 25k
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
Move x-content implementation to a separate classloader #83705
Conversation
Also delete duplicated tests, keeping them in x-content lib
Incremental progress - X-Content-split
X content split - iteration 2
@mark-vieira @nik9000 I think this is ready for another round of review. The implementation has changed so that the implementation jars are now exploded and embedded in the x-content jar in a hidden location. This alleviates the need to add anything additional to the classpath, or have any new artifacts published. @nik9000 Thanks for looking at Eclipse. It's about exactly what we anticipated. I'm not sure we should do anything. The hack you came up with is quite fragile and long term Eclipse is going to have more of these problems as we move to modules. An alternative hack would be to put the genereated resources directory on the classpath manually within the project. It's not much worse than what IntelliJ is doing automatically by reading the gradle model, but it still requires running any cli command that will trigger building the directory. I know it isn't what you want to hear, but I think the benefit of this change outweighs complexity added for the few developers using Eclipse. |
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 works well and LGTM other than a few comments. Thanks for iterating on this. I think this implementation is definitely better and more sustainable going forward.
libs/x-content/impl/build.gradle
Outdated
*/ | ||
|
||
apply plugin: 'elasticsearch.build' | ||
apply plugin: 'elasticsearch.publish' |
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.
Do we still need to publish this given we are effectively embedding it in the x-content jar?
libs/x-content/impl/build.gradle
Outdated
} | ||
|
||
tasks.named("jar").configure { | ||
archiveBaseName = "x-content-impl" |
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 should just set this on the project convention. That is, add archivesBaseName = "x-content-impl"
to the root of the build script
libs/x-content/impl/build.gradle
Outdated
* Side Public License, v 1. | ||
*/ | ||
|
||
apply plugin: 'elasticsearch.build' |
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.
I think we want to use the elasticsearch.java
plugin here since build
implicitly applies the publish plugin which I don't believe we want.
libs/x-content/build.gradle
Outdated
@@ -47,3 +60,24 @@ tasks.named("dependencyLicenses").configure { | |||
} | |||
|
|||
tasks.named("jarHell").configure { enabled = false } |
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.
Why are we disabling this?
libs/x-content/build.gradle
Outdated
|
||
File generatedResourcesDir = new File(buildDir, 'generated-resources') | ||
def generateProviderManifest = tasks.register("generateProviderManifest") { | ||
File manifestFile = new File(generatedResourcesDir, "MANIFEST.TXT") |
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.
I feel like this should have a more descriptive name. Also confusing given we'll have a MANIFEST.TXT
and MANIFEST.MF
in the JAR.
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.
I actually named it manifest since it sort of parallels the jar manifest. I'm not tied to the name, though. I just don't have a better one. Do you have a suggestion?
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.
Something with "embedded" in the name?
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.
I pushed "LISTING.TXT", wdyt?
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.
Works for me.
libs/x-content/src/main/java/org/elasticsearch/xcontent/internal/EmbeddedImplClassLoader.java
Outdated
Show resolved
Hide resolved
We should apply a custom attribute for the E.g.
This still results in the original raised circular dependency issue but with a clearer output:
The root problem keeps being that running |
thanks @rjernst. looks good to me |
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.
lgtm
x-content is a relatively well contained abstraction for parsing and generating json-like content. It is backed by Jackson, but consumers throughout Elasticsearch use the x-content interfaces and don't generally care about how Jackson is used. However, because x-content is a dependency of server, Jackson is also a dependency of server. Since all server dependencies must be exactly matched by plugins (and ES modules), upgrading Jackson is difficult since it must be done in lock step across the codebase.
This change isolates the Jackson implementation of x-content parsers and generators to a separate classloader. The code is loaded dynamically upon accessing any x-content functionality.
The x-content implementation is embedded inside the x-content jar, as a hidden set of resource files. These are loaded through a special classloader created to initialize the XContentProvider through service loader. One caveat to this approach is that IDEs will no longer trigger building the x-content implementation when it changes. However, running any test from the command line, or running a full Build in IntelliJ will trigger the directory to be built.
Most of the changes here are logistical, just moving methods and classes across to the implementation project. One common change to code using x-content is exception handling. This code relied on knowledge of Jackson exception types. That code now uses special exception types from x-content. Another change needed in a few places was now including jackson-core in plugins, since server no longer provides it.
The hope is that this change can be used as a model for future similar isolation of server dependencies.