Skip to content

[#2771] feat(spark): Support Spark 4.2#2772

Draft
LuciferYang wants to merge 2 commits into
apache:masterfrom
LuciferYang:spark-4.2-support
Draft

[#2771] feat(spark): Support Spark 4.2#2772
LuciferYang wants to merge 2 commits into
apache:masterfrom
LuciferYang:spark-4.2-support

Conversation

@LuciferYang

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Add a mutually-exclusive spark4.2 Maven profile that builds the existing client-spark/spark4 module against Apache Spark 4.2.0, mirroring the spark4.1 profile added in #2751.

  • Root pom.xml: new spark4.2 profile — a structural clone of spark4.1, differing only in spark.version=4.2.0, scala.version=2.13.18, netty.version=4.2.13.Final, jackson.version=2.21.2.
  • client-spark/spark4/pom.xml: spark4.2 profile reuses the src/main/java-spark4_1 compat source root (the 4.1 Spark4Compat shim).
  • client-spark/extension/pom.xml: spark4.2 profile reuses the scala-jakarta servlet source root.
  • lz4: introduce a ${lz4.groupId} property (org.lz4 by default, at.yawk.lz4 under spark4.2); the two integration-test modules declare ${lz4.groupId}:lz4-java, and both coordinates are version-managed in root dependencyManagement (org.lz4:1.8.1, at.yawk.lz4:1.11.0).
  • CI: parallel.yml gains a spark4.2 / java 17 matrix entry; sequential.yml gains a -Pspark4.2 step gated on java-version == 17.

No new Java source and no new Maven module. client-spark/spark4-shaded needs no change (its bouncycastle/jctools relocations are already global).

Why are the changes needed?

Fix: #2771

Users should be able to build and run Uniffle's Spark client against Spark 4.2.0 with full parity to the existing 4.1 support.

The three cross-major APIs called from client-spark/spark4 are byte-identical between 4.1.1 and 4.2.0 (verified with javap), so no shim change is required:

API 4.1.1 4.2.0
MapStatus.apply(BlockManagerId, long[], long, long) 4-arg identical
ExternalSorter(…, RowBasedChecksum[]) ctor 6-arg identical
WebUIPage.render(jakarta…HttpServletRequest) jakarta identical

Dependency notes:

  • jackson → 2.21.2 (required): Spark 4.2.0 ships jackson-module-scala_2.13 2.21.2, which validates the classpath jackson-databind on registration and throws in RDDOperationScope's static initializer if it is outside [2.21.0, 2.22.0). Same class of failure the 4.1 work hit.
  • netty → 4.2.13.Final: matches what Spark 4.2.0 was compiled/tested against (still Netty 4.2, same major as 4.1's 4.2.7, so [#2750] feat(spark): Support Spark 4.1 #2751's NioIoHandler/refCnt handling still applies — no code change).
  • lz4 → at.yawk.lz4:1.11.0 (required): Spark 4.2.0 bumped lz4 to 1.11.0, and the lz4-java project relocated its coordinates from org.lz4 to at.yawk.lz4 after 1.8.1 (org.lz4 only publishes a 1.8.1 relocation stub). Spark 4.2's shuffle path calls LZ4BlockInputStream.newBuilder() (added in the 1.11 line); without the bump the integration tests fail at runtime with NoSuchMethodError. A managed at.yawk.lz4:1.11.0 alone does not win because the modules declare org.lz4 and Maven's relocation carries 1.8.1's version — hence the ${lz4.groupId} flip.
  • hadoop / jetty / log4j / slf4j / commons-lang3 deltas are deferred; the profile keeps the 4.1 values.

Does this PR introduce any user-facing change?

No behavioral change. Adds a new opt-in -Pspark4.2 build profile. Existing -Pspark4 (4.0.2) and -Pspark4.1 (4.1.1) are unchanged.

How was this patch tested?

Verified locally on JDK 17 (Zulu 17.0.18):

  1. mvn clean install -Pspark4.2 -DskipTests — compiles + shades against 4.2.0 (spark-core/sql/catalyst 4.2.0, scala 2.13.18, netty 4.2.13.Final, jackson 2.21.2, lz4 1.11.0 resolved).
  2. mvn clean install -Pspark4.1 -DskipTests + integration tests — 4.1.1 build and AQERepartitionTest / MapSideCombineTest still green (lz4 stays org.lz4:1.8.1); confirms no regression.
  3. AQERepartitionTest, MapSideCombineTest pass under -Pspark4.2.
  4. TransportFrameDecoderTest (2 tests) passes on Netty 4.2.13 under -Pspark4.2.
  5. RepartitionWithLocalFileRssTest (NOOP/ZSTD/LZ4 codecs) passes under -Pspark4.2 — exercises the lz4 runtime path.
  6. dev/scripts/checkshade.sh on the spark4.2 shaded jar — "check success", 0 unshaded classes; bouncycastle/jctools relocated.

CI runs the same via the new spark4.2 matrix entry / -Pspark4.2 step.

Add a mutually-exclusive `spark4.2` Maven profile that builds the existing
client-spark/spark4 module against Apache Spark 4.2.0, mirroring spark4.1.

The three cross-major APIs called from the spark4 module (MapStatus.apply,
the ExternalSorter ctor, WebUIPage.render) are byte-identical between 4.1.1
and 4.2.0 (verified with javap), so the src/main/java-spark4_1 Spark4Compat
shim and the scala-jakarta servlet variant are reused as-is — no new source.

Dependency pins for the profile:
- spark.version 4.2.0, scala.version 2.13.18
- netty.version 4.2.13.Final (what Spark 4.2.0 ships; still Netty 4.2)
- jackson.version 2.21.2 (jackson-module-scala 2.21.2 requires databind in
  [2.21.0, 2.22.0), else RDDOperationScope's initializer throws)
- lz4 at.yawk.lz4:1.11.0 (Spark 4.2 calls LZ4BlockInputStream.newBuilder,
  added in the 1.11 line; lz4-java relocated org.lz4 -> at.yawk.lz4 after
  1.8.1). Introduce a ${lz4.groupId} property, flipped to at.yawk.lz4 in the
  spark4.2 profile; both coordinates are version-managed in root DM.

CI: add a spark4.2 / java 17 matrix entry (parallel.yml) and a -Pspark4.2
step (sequential.yml).
@LuciferYang
LuciferYang marked this pull request as draft July 22, 2026 08:13
@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

Test Results

 3 833 files  +  216   3 833 suites  +216   8h 8m 55s ⏱️ + 26m 24s
 1 265 tests ±    0   1 254 ✅ +    1  11 💤 ± 0  0 ❌  - 1 
19 153 runs  +1 098  19 105 ✅ +1 088  48 💤 +11  0 ❌  - 1 

Results for commit 1512b33. ± Comparison against base commit 20167ff.

♻️ This comment has been updated with latest results.

…rofile

The prior commit added at.yawk.lz4:lz4-java:1.11.0 to the root
dependencyManagement with a hardcoded version. Because org.lz4:lz4-java:1.8.1
is a relocation stub that Maven rewrites to at.yawk.lz4:1.8.1, that unconditional
1.11.0 entry version-managed every transitive lz4 consumer (server, client,
coordinator, cli, ...) up to 1.11.0 in the default build and all non-spark4.2
profiles -- an out-of-scope, undocumented change (the comments claimed the
opposite), overriding the 1.8.1 pin from apache#2693.

Route the at.yawk.lz4 version through a new ${lz4.version} property: 1.8.1 by
default (restores the pre-PR state for the default build and spark2/3/4/4.1),
1.11.0 only in the spark4.2 profile where Spark needs
LZ4BlockInputStream.newBuilder(). Also fix the misleading relocation comments
and document that the spark4-shaded org.lz4 exclusion must not be parameterized
(Maven matches exclusions on the as-declared coordinate; flipping it would leak
at.yawk.lz4 into the shaded jar under -Pspark4.2).

Verified: default build client/coordinator/server-common resolve
at.yawk.lz4:1.8.1 again; -Pspark4.2 spark4 client + integration tests stay on
1.11.0 and pass; -Pspark4.1 unaffected; spark4.2 shaded jar still has no
net.jpountz classes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Improvement] Support Spark 4.2

1 participant