Skip to content

Build: Add Java 25 support by adding arrow-memory-unsafe to dependencies#15931

Closed
wangyum wants to merge 1 commit intoapache:mainfrom
wangyum:java25
Closed

Build: Add Java 25 support by adding arrow-memory-unsafe to dependencies#15931
wangyum wants to merge 1 commit intoapache:mainfrom
wangyum:java25

Conversation

@wangyum
Copy link
Copy Markdown
Member

@wangyum wangyum commented Apr 10, 2026

Background

The Problem: Default Netty Allocator Fails on Java 25
When running Apache Iceberg / Spark with Apache Arrow on Java 25, the default memory allocator (arrow.allocation.manager.type=Netty) will crash our jobs with an ExceptionInInitializerError and UnsupportedOperationException.

This happens because the older version of Netty bundled inside Iceberg relies heavily on deep JVM internals to access memory. Specifically, Java 25 completely removed the SecurityManager (JEP 486) and changed internal memory structures (JEP 471) that Netty was looking for. Because these internal classes and fields no longer exist, no amount of --add-opens flags will fix the crash.

The Solution: Use the Unsafe Allocator
To avoid this issue on Java 25, we must bypass Netty entirely by adding the following to our Spark configuration:

spark.executor.extraJavaOptions=-Darrow.allocation.manager.type=Unsafe
spark.driver.extraJavaOptions=-Darrow.allocation.manager.type=Unsafe

But it will throw java.lang.ClassNotFoundException: org.apache.arrow.memory.UnsafeAllocationManager. So we need to add arrow-memory-unsafe to dependencies.

Closes #15930

How to test

  1. Download iceberg-java25.tgz
  2. tar -zxf iceberg-java25.tgz && cd iceberg-java25
  3. Build with Java 17: /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/bin/javac -cp ".:*" Reproducer.java
  4. Run with Java 25: /Library/Java/JavaVirtualMachines/zulu-25.jdk/Contents/Home/bin/java -cp ".:*" --add-opens=java.base/java.nio=ALL-UNNAMED Reproducer, it will throw exception. We should add -Darrow.allocation.manager.type=Unsafe to run it: /Library/Java/JavaVirtualMachines/zulu-25.jdk/Contents/Home/bin/java -cp ".:*" --add-opens=java.base/java.nio=ALL-UNNAMED -Darrow.allocation.manager.type=Unsafe Reproducer

…lity

Arrow's NettyAllocationManager static initializer fails on Java 25 (JEP 471)
because PooledByteBufAllocatorL calls EmptyByteBuf.memoryAddress() via
sun.misc.Unsafe, which is no longer supported. Both arrow-memory-netty and
arrow-memory-unsafe ship org.apache.arrow.memory.DefaultAllocationManagerFactory
and when the netty variant loads first the JVM crashes at startup.

Changes:
- Remove arrow-memory-netty from iceberg-arrow; use arrow-memory-unsafe
  exclusively as the Arrow allocator
- Add defensive netty excludes to arrow-memory-unsafe (consistent with
  arrow-vector exclusions in the same block)
- Add netty-common library alias to libs.versions.toml (version.ref =
  netty-buffer, since Netty publishes all modules at the same version)
- Use libs.netty.common catalog alias for ArrowReaderTest instead of an
  inline string interpolation against the wrong version key
- Remove dead arrow-memory-netty alias from libs.versions.toml

Closes apache#15930

Co-Authored-By: Claude (claude-sonnet-4-6) <<EMAIL_ADDRESS>>
@wangyum
Copy link
Copy Markdown
Member Author

wangyum commented Apr 11, 2026

Fixed it by adding --sun-misc-unsafe-memory-access=allow on the Spark executor.

@wangyum wangyum closed this Apr 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Arrow memory allocation fails on Java 25: NettyAllocationManager static initializer throws UnsupportedOperationException

1 participant