You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: exclude netty from bundle jars to prevent split-package conflicts (#458)
## Summary
The `lance-spark-bundle-*` jars currently ship a partial copy of Netty
(specifically `io/netty/buffer/*` and `io/netty/util/*` from
`io.netty:netty-common` and `io.netty:netty-buffer`, pulled transitively
via Arrow's `arrow-memory-netty` at `compile` scope). Netty's
`channel/transport` classes are **not** included and are expected from
the Spark runtime.
This split-package layout is fragile. Classpath ordering decides which
jar wins per package, and a version skew between the bundled
`util`/`buffer` packages and the runtime's `channel`/`transport`
packages blows up at super-call time.
### Reproducer
Using the Spark 4.1 bundle against a Spark runtime with a mismatched
Netty in `$SPARK_HOME/jars/`:
```
java.lang.NoSuchMethodError: 'void io.netty.util.concurrent.SingleThreadEventExecutor.<init>(
io.netty.util.concurrent.EventExecutorGroup, java.util.concurrent.Executor,
boolean, boolean, int, io.netty.util.concurrent.RejectedExecutionHandler)'
at io.netty.channel.SingleThreadEventLoop.<init>(SingleThreadEventLoop.java:83)
at io.netty.channel.SingleThreadIoEventLoop.<init>(SingleThreadIoEventLoop.java:102)
at io.netty.channel.MultiThreadIoEventLoopGroup.newChild(MultiThreadIoEventLoopGroup.java:212)
...
at org.apache.spark.network.util.NettyUtils.createEventLoop(NettyUtils.java:86)
at org.apache.spark.rpc.netty.NettyRpcEnvFactory.create(NettyRpcEnv.scala:499)
at org.apache.spark.SparkContext.<init>(SparkContext.scala:501)
```
The 4.2 `SingleThreadIoEventLoop` (from Spark's netty-transport) calls
the 6-arg super-ctor on `SingleThreadEventExecutor`, but the resolved
`SingleThreadEventExecutor` is the 4.1 version which only has a 5-arg
ctor.
### Fix
Exclude `io.netty:*` from the shade plugin `artifactSet` in each bundle
pom. Spark owns Netty at runtime and hard-references `io.netty.*`
directly — shading/relocation isn't viable, so the bundle must defer
entirely to the runtime.
Arrow's `arrow-memory-netty-buffer-patch` classes (e.g. `NettyArrowBuf`,
`PooledByteBufAllocatorL`) also live in the `io.netty.buffer` package to
reach package-private APIs. They ship under a different groupId and
remain in the bundle — they're Arrow's code, not Netty's, and don't
participate in Netty version conflicts.
Applied to all 6 bundle modules: 3.4 / 3.5 / 4.0 / 4.1 across Scala 2.12
and 2.13.
### Verification
Rebuilt `lance-spark-bundle-4.1_2.13` and confirmed:
- Before: bundle contained
`io/netty/util/concurrent/SingleThreadEventExecutor.class` + full Netty
util/buffer packages from `io.netty:netty-common` 4.2.7 and
`io.netty:netty-buffer` 4.2.7.
- After: only 9 `io/netty/buffer/*` entries remain, all from
`arrow-memory-netty-buffer-patch` — no real Netty classes.
## Test plan
- [x] `./mvnw -pl lance-spark-bundle-4.1_2.13 -am package -DskipTests`
succeeds
- [x] `unzip -l` on the rebuilt bundle confirms no Netty jar contents
remain (only Arrow's netty-buffer-patch classes)
- [ ] Run the failing PySpark integration against the rebuilt 4.1 bundle
to confirm the `NoSuchMethodError` is gone
- [ ] Spot-check one 3.x bundle build to confirm identical behavior
across Spark versions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
0 commit comments