[SPARK-42539][SQL][HIVE] Eliminate separate classloader when using 'builtin' Hive version for metadata client #40224
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.
What changes were proposed in this pull request?
When using the 'builtin' Hive version for the Hive metadata client, do not create a separate classloader, and rather continue to use the overall user/application classloader (regardless of Java version). This standardizes the behavior for all Java versions with that of Java 9+. See SPARK-42539 for more details on why this approach was chosen.
Please note that this is a re-submit of #40144. That one introduced test failures, and potentially a real issue, because the PR works by setting
isolationOn = false
forbuiltin
mode. In addition to adjusting the classloader,HiveClientImpl
relies onisolationOn
to determine if it should use an isolated copy ofSessionState
, so the PR inadvertently switched to using a sharedSessionState
object. I think we do want to continue to have the isolated session state even inbuiltin
mode, so this adds a new flagsessionStateIsolationOn
which controls whether the session state should be isolated, separately from theisolationOn
flag which controls whether the classloader should be isolated. Default behavior is forsessionStateIsolationOn
to be set equal toisolationOn
, but forbuiltin
mode, we override it to enable session state isolated even though classloader isolation is turned off.Why are the changes needed?
Please see a much more detailed description in SPARK-42539. The tl;dr is that user-provided JARs (such as
hive-exec-2.3.8.jar
) take precedence over Spark/system JARs when constructing the classloader used byIsolatedClientLoader
on Java 8 in 'builtin' mode, which can cause unexpected behavior and/or breakages. This violates the expectation that, unless user-first classloader mode is used, Spark JARs should be prioritized over user JARs. It also seems that this separate classloader was unnecessary from the start, since the intent of 'builtin' mode is to use the JARs already existing on the regular classloader (as alluded to here). The isolated clientloader was originally added in #5876 in 2015. This bit in the PR description is the only mention of the behavior for "builtin":I can't follow the logic here; the user classloader clearly has all of the necessary Hive JARs, since that's where we're getting the JAR URLs from, so we could just use that directly instead of grabbing the URLs. When this was initially added, it only used the JARs from the user classloader, not any of its parents, which I suspect was the motivating factor (to try to avoid more Spark classes being duplicated inside of the isolated classloader, I guess). But that was changed a month later anyway in #6435 / #6459, so I think this may have basically been deadcode from the start. It has also caused at least one issue over the years, e.g. SPARK-21428, which disables the new-classloader behavior in the case of running inside of a CLI session.
Does this PR introduce any user-facing change?
No, except to protect Spark itself from potentially being broken by bad user JARs.
How was this patch tested?
This includes a new unit test in
HiveUtilsSuite
which demonstrates the issue and shows that this approach resolves it. It has also been tested on a live cluster running Java 8 and Hive communication functionality continues to work as expected.Unit tests failing in #40144 have been locally tested (
HiveUtilsSuite
,HiveSharedStateSuite
,HiveCliSessionStateSuite
,JsonHadoopFsRelationSuite
).