(WIP) Support explicit dependencies between extensions.#16968
Closed
georgew5656 wants to merge 19 commits intoapache:masterfrom
Closed
(WIP) Support explicit dependencies between extensions.#16968georgew5656 wants to merge 19 commits intoapache:masterfrom
georgew5656 wants to merge 19 commits intoapache:masterfrom
Conversation
Contributor
Author
|
closing in favor of #16973 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Allow specifying extensions between extensions without having to explicitly install jars in multiple places.
Description
Currently, in order to have extension A depend on extension B, you have to explicitly include extension B as a build dependency in extension A's pom.xml. This cause the jar for extension B to be included in extension A's directory and loaded as a module.
This can lead to some weird behavior e.g. the following bug linked from #16929 caused by druid-kafka-extraction-namespace depending on druid-lookups-cached-global.
to get around this issue, my proposed fix is to allow chaining classloaders without having to actually copy jars. e.g. extension A won't actually have extension B's jar (we include the dependency as provided in the pom.xml). when extension A is loading classes, it will try to use extension B's classloader to find classes it can't find.
Fixed the bug ...
Renamed the class ...
Added a forbidden-apis entry ...
We currently support two kinds of classloaders for each extension (extension-first or not). hadoop always uses the non extension-first classloader and other druid services check the druid.extensions.useExtensionClassloaderFirst property. this made it a little more annoying to implement chained classloading (see ExtensionLoader), but I didn't think we could deprecate this behavior so I left it in. I had to add a StandardClassLoader class because we were just using a regular UrlClassLoader object for the non extension-first classloader. In both StandardClassLoader and ExtensionFirstClassLoader i added the logic to check other extension's classloaders for classes. this is the part of the code i'd like some more detailed feedback on.
I added a root level extension-dependencies.json file to specify inter-extension dependencies. the kafka/global cached lookup dependency is included here. When building druid bundles, maven copies this file into the extensions/ directory so the PullDependencies command can read it. I was hoping to just have the PullDependencies command to copy the json over instead but the Main command that runs PullDependencies actually needs extensions to be loaded (https://github.com/apache/druid/blob/master/services/src/main/java/org/apache/druid/cli/Main.java#L98), so this doesn't work.
Since PullDependencies can delete the extensions/ directory before copying jars in, I had to update the logic to replace the extension-dependencies.json file after the extensions/ directory has been repopulated.
The logic to actually set dependencies from extension-dependencies.json in extension classloaders is in ExtensionsLoader.
I tested this with druid-kafka-extraction-namespace and druid-lookups-cached-global and everything seems to work okay.
I haven't added any unit tests yet because I want to get feedback on whether this approach seems reasonable.
Release note
Key changed/added classes in this PR
ExtensionLoaderExtensionFirstClassLoaderStandardClassLoaderPullDependenciesThis PR has: