[VL] Take Arrow out of the bundle for Spark 4.x and drop dead arrow-dataset - #12737
[VL] Take Arrow out of the bundle for Spark 4.x and drop dead arrow-dataset#12737jackylee-ch wants to merge 7 commits into
Conversation
2ac5922 to
7aeb578
Compare
|
Run Gluten Clickhouse CI on x86 |
…row-dataset
Test-only, two independent parts.
1) Spark 4.x uses the Arrow that Spark itself ships, instead of gluten
bundling its own copy. Two new properties drive it:
arrow.deps.scope compile -> provided (spark-4.0 / 4.1)
spark.arrow.exclusion.groupId org.apache.arrow -> none
The second one parameterizes the `<exclusion>` groupId on the Spark
dependencies in dependencyManagement, so those exclusions stop matching and
Spark's own Arrow flows through transitively - including into the gluten-ut
test classpath, which is what `provided` alone cannot do.
arrow.version now matches what each Spark actually ships:
spark-4.0 -> 18.1.0, spark-4.1 -> 18.3.0.
Spark 3.3 / 3.4 / 3.5 keep 15.0.0 at `compile` scope, unchanged.
package/pom.xml needs no change: under `provided` the Arrow artifacts never
enter the shade artifactSet, so the org.apache.arrow relocation becomes a
no-op on Spark 4.x while still applying on 3.x.
2) Drops arrow-dataset. `ArrowNativeMemoryPool` and `ArrowReservationListener`
were its only main-source users and have had no callers since apache#12130 removed
the Arrow-CSV scan path. The three tests under backends-velox .../fs/ that
used it exercise Arrow's own FileSystemDatasetFactory, not gluten code.
Bundle size:
spark-4.1 138.6 MB -> 56.4 MB compressed (600.6 -> 299.6 uncompressed)
spark-3.5 138.6 MB -> 68.6 MB compressed
Arrow left in the spark-4.1 bundle: arrow-c-data only, 35 classes plus 0.9 MB
of libarrow_cdata_jni - Spark does not ship arrow-c-data and its JNI symbols
bind to the original package names, so it cannot be provided or relocated.
Generated-by: Claude claude-opus-4.7
7aeb578 to
1393c1c
Compare
|
Run Gluten Clickhouse CI on x86 |
…ataset (apache#12737) Backport of apache#12737. Two independent parts: 1) Spark 4.x uses the Arrow that Spark itself ships, instead of gluten bundling its own copy. Two new properties drive it: arrow.deps.scope compile -> provided (spark-4.0 / 4.1) spark.arrow.exclusion.groupId org.apache.arrow -> none The second parameterizes the <exclusion> groupId on the Spark dependencies in dependencyManagement, so those exclusions stop matching and Spark's own Arrow flows through transitively - including into the gluten-ut test classpath, which provided alone cannot reach. arrow.version now matches what each Spark actually ships: spark-4.0 -> 18.1.0, spark-4.1 -> 18.3.0. Spark 3.3/3.4/3.5 keep 15.0.0 at compile scope, unchanged. 2) Drops arrow-dataset. ArrowNativeMemoryPool and ArrowReservationListener were its only main-source users and have had no callers since apache#12130 removed the Arrow-CSV scan path. The three tests under backends-velox/.../fs/ that used it exercise Arrow's own FileSystemDatasetFactory, not gluten code. Generated-by: Claude claude-opus-4.7
|
Run Gluten Clickhouse CI on x86 |
|
Run Gluten Clickhouse CI on x86 |
|
@zhouyuan @zhztheplayer PTAL |
There was a problem hiding this comment.
Pull request overview
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Reduce Velox bundle size and Spark 4.x Arrow conflicts by relying on Spark-provided Arrow at runtime and removing unused Arrow Dataset integration.
Changes:
- Switch Spark 4.x builds to use Arrow dependencies as
providedand allow Spark’s transitive Arrow to flow through by parameterizing Arrow exclusions. - Remove dead
arrow-datasetusage (dependencies, Arrow memory pool classes, and dataset-based filesystem tests). - Extend shading verification to detect shaded Arrow references in constant pools and keep
org.apache.arrow.util.**unshaded for Arrow C-Data.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pom.xml | Add arrow.deps.scope / spark.arrow.exclusion.groupId properties and Spark 4.x profile overrides for provided Arrow. |
| package/pom.xml | Update shading relocation excludes to keep org.apache.arrow.util.** unshaded alongside C-Data/memory/vector. |
| gluten-arrow/pom.xml | Scope Arrow deps via ${arrow.deps.scope}; remove arrow-dataset; prevent arrow-c-data from reintroducing compile-scope Arrow deps. |
| dev/check-arrow-c-shading.sh | Enhance verification to scan constant pools for shaded Arrow references. |
| backends-velox/pom.xml | Re-declare Arrow deps so they remain available on compile classpath when upstream Arrow is provided. |
| gluten-arrow/src/main/java/org/apache/gluten/memory/arrow/pool/ArrowReservationListener.java | Remove unused listener tied to arrow-dataset. |
| gluten-arrow/src/main/java/org/apache/gluten/memory/arrow/pool/ArrowNativeMemoryPool.java | Remove unused memory-pool wrapper tied to arrow-dataset. |
| backends-velox/src/test/java/org/apache/gluten/fs/TestNativeDataset.java | Remove dataset-based test base class (Arrow dataset). |
| backends-velox/src/test/java/org/apache/gluten/fs/TestDataset.java | Remove dataset-based test utilities (Arrow dataset). |
| backends-velox/src/test/java/org/apache/gluten/fs/CsvWriteSupport.java | Remove CSV temp writer used only by Arrow dataset tests. |
| backends-velox/src/test/java/org/apache/gluten/fs/ArrowFilesystemTest.java | Remove Arrow FileSystemDatasetFactory test (not exercising Gluten code). |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…r scope
1) check-arrow-c-shading.sh: accept shade-package-name as an argument
(passed from package/pom.xml via ${gluten.shade.packageName}) instead
of hard-coding the prefix. Expand the constant-pool regex to include
underscores and dashes — valid JVM internal-name characters that were
previously missed.
2) Introduce ${arrow-memory.scope} (default: runtime) for the allocator
implementation artifact (${arrow-memory.artifact}). This restores the
pre-PR 'runtime' scope on Spark 3.x instead of widening it to 'compile'
via ${arrow.deps.scope}. Spark 4.x profiles override it to 'provided'.
Gluten never compiles against the allocator impl — CheckAllocator
discovers it by classpath scan at runtime — so compile exposure is
unnecessary.
691aed4 to
b02e7c0
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Suppressed comments (2)
dev/check-arrow-c-shading.sh:111
- The script claims to validate
org/apache/arrow/c/**constant pools, but the unzip pattern only extractsorg/apache/arrow/c/*(non-recursive). That will skip any classes underorg/apache/arrow/c/jni/(which are also explicitly excluded from relocation inpackage/pom.xml), so shaded constant-pool references there would go undetected. Recommendation: extract and scan bothorg/apache/arrow/c/*andorg/apache/arrow/c/jni/*(or use a recursive pattern) and update the existence check accordingly.
unzip -qo "$JAR" 'org/apache/arrow/c/*' -d "$WORKDIR/all" 2>/dev/null || true
if compgen -G "$WORKDIR/all/org/apache/arrow/c/*.class" > /dev/null; then
refs=$(grep -rahoE "${SHADE_SLASHES}/org/apache/arrow/[a-zA-Z0-9_$/-]+" \
"$WORKDIR/all/org/apache/arrow/c" 2>/dev/null | sort -u || true)
if [[ -n "$refs" ]]; then
echo " FAIL org/apache/arrow/c/** — calls into gluten-shaded Arrow:"
echo "$refs" | sed 's/^/ /'
failures=$((failures + 1))
backends-velox/pom.xml:137
- This PR duplicates a fairly large, exclusion-heavy set of Arrow dependency declarations that are also present in
gluten-arrow/pom.xml. That creates a drift risk (e.g., future exclusions/scope tweaks applied to one module but not the other). Recommendation: centralize these Arrow dependency definitions (including exclusions and scopes) in a shared place such as parentdependencyManagement(or a dedicated Maven profile/BOM-style module), and have both modules reference the managed dependencies without re-stating the full blocks.
<!--
Re-declared here because `provided` scope is not transitive: when
${arrow.deps.scope} is `provided` (Spark 4.x), gluten-arrow's Arrow
dependencies do not reach this module's compile classpath on their own.
Under `compile` (Spark 3.x) these are redundant but harmless.
The allocator implementation (${arrow-memory.artifact}) is the exception:
it is never compiled against, only discovered on the classpath at runtime,
so it uses ${arrow-memory.scope} (runtime on Spark 3.x, provided on 4.x)
rather than ${arrow.deps.scope}.
-->
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>${arrow-memory.artifact}</artifactId>
<version>${arrow.version}</version>
<scope>${arrow-memory.scope}</scope>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-memory-core</artifactId>
<version>${arrow.version}</version>
<scope>${arrow.deps.scope}</scope>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-vector</artifactId>
<version>${arrow.version}</version>
<scope>${arrow.deps.scope}</scope>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
|
Run Gluten Clickhouse CI on x86 |
1 similar comment
|
Run Gluten Clickhouse CI on x86 |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Suppressed comments (2)
dev/check-arrow-c-shading.sh:107
- The constant-pool scan only extracts
org/apache/arrow/c/*, so it can miss shaded references in subpackages likeorg/apache/arrow/c/jni/*. Since the diagnostic text claims to validateorg/apache/arrow/c/**, the unzip pattern and existence check should be recursive (at least one level) so the guard can't pass vacuously.
mkdir -p "$WORKDIR/all"
unzip -qo "$JAR" 'org/apache/arrow/c/*' -d "$WORKDIR/all" 2>/dev/null || true
if compgen -G "$WORKDIR/all/org/apache/arrow/c/*.class" > /dev/null; then
refs=$(grep -rahoE "${SHADE_SLASHES}/org/apache/arrow/[a-zA-Z0-9_$/-]+" \
"$WORKDIR/all/org/apache/arrow/c" 2>/dev/null | sort -u || true)
dev/check-arrow-c-shading.sh:61
SHADE_SLASHESis intended to convert the dotted shade package (e.g.org.apache.gluten.shaded) into a slashed JVM internal-name prefix, but${SHADE_PACKAGE//.//}removes dots instead of replacing them with/. That makes the constant-pool scan regex never match and can let shaded references slip through undetected.
This issue also appears on line 103 of the same file.
# Dotted form for javap signatures, slashed form for JVM internal names in
# constant pools. `.` is escaped so the dotted form is a literal regex.
SHADE_PACKAGE="${2:-org.apache.gluten.shaded}"
SHADE_DOTS_RE="${SHADE_PACKAGE//./\\.}"
SHADE_SLASHES="${SHADE_PACKAGE//.//}"
|
@jackylee-ch in Gluten there is an extra profile to allow users to pick arrow-memory-netty based allocator (https://github.com/apache/gluten/blob/main/pom.xml#L1478-L1487), will this patch block this usage? |
| <arrow.version>18.1.0</arrow.version> | ||
| <arrow.deps.scope>provided</arrow.deps.scope> | ||
| <arrow-memory.scope>provided</arrow-memory.scope> | ||
| <!-- Matches no groupId: let Spark's own Arrow through. --> |
There was a problem hiding this comment.
is there a way to verify Gluten is using the arrow jar from spark distribution?
…ataset (apache#12737) Backport of apache#12737. Two independent parts: 1) Spark 4.x uses the Arrow that Spark itself ships, instead of gluten bundling its own copy. Two new properties drive it: arrow.deps.scope compile -> provided (spark-4.0 / 4.1) spark.arrow.exclusion.groupId org.apache.arrow -> none The second parameterizes the <exclusion> groupId on the Spark dependencies in dependencyManagement, so those exclusions stop matching and Spark's own Arrow flows through transitively - including into the gluten-ut test classpath, which provided alone cannot reach. arrow.version now matches what each Spark actually ships: spark-4.0 -> 18.1.0, spark-4.1 -> 18.3.0. Spark 3.3/3.4/3.5 keep 15.0.0 at compile scope, unchanged. 2) Drops arrow-dataset. ArrowNativeMemoryPool and ArrowReservationListener were its only main-source users and have had no callers since apache#12130 removed the Arrow-CSV scan path. The three tests under backends-velox/.../fs/ that used it exercise Arrow's own FileSystemDatasetFactory, not gluten code. Generated-by: Claude claude-opus-4.7
Copilot follow-up: the unzip glob 'org/apache/arrow/c/*' was unzip-implementation-defined for recursion, and the existence check compgen -G '.../c/*.class' looked only at the top level. Name the c/jni subpackage explicitly so the constant-pool scan cannot vacuously pass if all Arrow.c.jni classes ever move under a shaded pattern. Verified end-to-end: a synthetic bundle whose only shaded reference lives inside org/apache/arrow/c/jni/ now trips the guard (exit=1).
|
Run Gluten Clickhouse CI on x86 |
Turn the manual 'unzip -l bundle.jar | grep arrow' check into a build-
time assertion. Pass ${arrow.deps.scope} into check-arrow-c-shading.sh
so it validates the jar's Arrow content against the declared scope:
- scope=provided (Spark 4.x): arrow-memory/arrow-vector MUST be
absent from the bundle. If a dependency ever regresses to
compile scope, the bundle silently re-inflates and re-introduces
the Spark-vs-gluten Arrow version conflict. Now fails the build.
- scope=compile (Spark 3.x): those packages MUST be present, so
an accidental scope narrowing on 3.x also fails the build.
Verified end-to-end against real 3.5 / 4.0 / 4.1 bundles: positive
cases pass, the two negative cases (3.5 declared provided, 4.0
declared compile) both trip the guard with a clear diagnostic.
|
Run Gluten Clickhouse CI on x86 |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Suppressed comments (1)
dev/check-arrow-c-shading.sh:127
- The constant-pool scan can be skipped unintentionally: the existence check relies on the
**glob, but the script never enablesglobstar(shopt -s globstar). On a default Bash config,compgen -G "$WORKDIR/.../**/*.class"won’t match nested classes (e.g.,org/apache/arrow/c/jni/*.class), so shaded constant-pool references could slip through without failing the build.
if compgen -G "$WORKDIR/all/org/apache/arrow/c/**/*.class" > /dev/null ||
compgen -G "$WORKDIR/all/org/apache/arrow/c/*.class" > /dev/null; then
refs=$(grep -rahoE "${SHADE_SLASHES}/org/apache/arrow/[a-zA-Z0-9_$/-]+" \
"$WORKDIR/all/org/apache/arrow/c" 2>/dev/null | sort -u || true)
|
No — |
The assertion added in the previous commit broke tpc-test jobs on
spark-3.x. Root cause: whether Arrow lands in the jar is a function of
the dependency closure and the shade artifactSet, not of
${arrow.deps.scope} alone. 'mvn install -Pspark-3.5 -Pbackends-velox'
(as run by the 'Build gluten-it' CI step, without the data-lake
profiles) produces an intermediate jar carrying no Arrow at all, so the
compile branch fired on a jar that was never meant to ship Arrow:
SKIP org/apache/arrow/c/ArrowArrayStream (not in bundle)
...
FAIL bundle content — arrow.deps.scope=compile but the bundle
ships no arrow-memory/arrow-vector classes
arrow-c-data is bundled on every profile precisely because Spark never
ships it, so its presence is the reliable marker for 'this jar is the
velox bundle'. Skip the content assertion when it is absent, matching
how the two shading checks already SKIP in that case.
Self-tested against real bundles and synthetic negatives:
spark-4.0/4.1 bundle + provided -> PASS
spark-3.5 bundle + compile -> PASS
Arrow-less intermediate jar + compile -> PASS (assertion skipped)
bundle with memory/vector + provided -> FAIL (guard still fires)
bundle without memory/vector + compile -> FAIL (guard still fires)
-Parrow-netty 3.x bundle + compile -> PASS
-Parrow-netty on 4.x (nothing bundled) -> PASS
netty leaked into a 4.x bundle -> FAIL (guard still fires)
no scope argument -> PASS (assertion skipped)
spark-3.3/3.4 inherit the same defaults as 3.5, so they take an
identical path.
|
Run Gluten Clickhouse CI on x86 |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Suppressed comments (1)
dev/check-arrow-c-shading.sh:135
- The existence check for extracted Arrow C-Data classes relies on a
**glob (compgen -G .../**/*.class) but the script never enablesglobstar, so Bash treats**literally. This can cause the constant-pool scan to be skipped when classes are only present underorg/apache/arrow/c/jni/(or any nested path), reducing the effectiveness of the new guard.
if compgen -G "$WORKDIR/all/org/apache/arrow/c/**/*.class" > /dev/null ||
compgen -G "$WORKDIR/all/org/apache/arrow/c/*.class" > /dev/null; then
What changes are proposed in this pull request?
Two independent, self-contained changes that shrink the Velox bundle and cut down
Arrow version conflicts on Spark 4.x.
1) Spark 4.x reuses the Arrow that Spark itself ships
Spark 4.x already ships an Arrow new enough for Gluten, so Gluten no longer needs to
carry its own copy inside the bundle. Two new properties drive this per Spark profile:
arrow.deps.scopecompileprovidedspark.arrow.exclusion.groupIdorg.apache.arrownonearrow.deps.scopeflips Gluten's Arrow dependencies fromcompile(shipped insidethe bundle) to
provided(compile-only; the Spark distribution owns Arrow at runtime).spark.arrow.exclusion.groupIdparameterizes the<exclusion>groupId on the Sparkdependencies in
dependencyManagement. Setting it tononemakes those exclusionsstop matching, so Spark's own Arrow flows through transitively — including into the
gluten-uttest classpath, whichprovidedscope alone cannot reach.Because
providedscope is not transitive,backends-velox(which importsorg.apache.arrow.{memory,vector}directly) re-declares those Arrow artifacts at${arrow.deps.scope}so it keeps its own compile classpath.arrow.versionnow matches what each Spark actually ships: spark-4.0 → 18.1.0,spark-4.1 → 18.3.0. Spark 3.3/3.4/3.5 keep 15.0.0 at
compile, unchanged.arrow-c-datastayscompile/bundled on every Spark version: Spark ships neitherarrow-c-datanor itslibarrow_cdata_jni, and its JNI symbols bind to the originalpackage names, so it can be neither
providednor relocated. Sinceorg.apache.arrow.c.*reaches into
org.apache.arrow.util.*(Preconditions,AutoCloseables,Collections2)from its constructors — references that live in the constant pool, not in any public
signature —
org.apache.arrow.util.**is now also excluded from relocation inpackage/pom.xml. Otherwise, once Arrow is no longer bundled, those shaded call siteswould have no target on the classpath and throw
ClassNotFoundException.dev/check-arrow-c-shading.shis extended to scan constant pools (not just methodsignatures) to guard this.
package/pom.xmlneeds no change to its shading logic: underprovidedthe Arrowartifacts never enter the shade artifactSet, so the
org.apache.arrowrelocation is ano-op on 4.x while still applying on 3.x.
Resulting bundle sizes:
The only Arrow left in the spark-4.1 bundle is
arrow-c-data— 35 classes plus ~0.9 MBof
libarrow_cdata_jni.2) Drop dead arrow-dataset
ArrowNativeMemoryPool/ArrowReservationListenerwere the only main-source users ofarrow-dataset, and have had no callers since #12130 removed the Arrow-CSV scan path.This PR removes both classes, the
arrow-datasetdependency, and the threebackends-velox/.../fs/tests, which exercised Arrow's ownFileSystemDatasetFactoryrather than any Gluten code.
Note for reviewers
On Spark 4.x the runtime Arrow allocator changes from
arrow-memory-unsafetoarrow-memory-netty: Gluten's defaultarrow-memory.artifactis stillarrow-memory-unsafe, but underprovidedscope it is no longer on the runtimeclasspath, while Spark 4.x ships
arrow-memory-netty. Arrow'sCheckAllocatorthereforeselects the Netty allocator. Both expose off-heap
ArrowBufwith a stablememoryAddress(), so JNI address hand-off to native is unaffected.How was this patch tested?
gluten-ut/spark40andgluten-ut/spark41suites plus the TPC-H / TPC-DS
gluten-itruns invelox_backend_x86.yml— exercisesthe
providedclasspath end to end (Spark's own Arrow on the runtime classpath).arrow-c-dataclasses reference the unshaded Apache Arrow API inboth method signatures and constant pools via the extended
dev/check-arrow-c-shading.sh.Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude claude-opus-4.7