Skip to content

build: strip release cdylib to shrink the JNI native library - #8314

Merged
Xuanwo merged 1 commit into
lance-format:mainfrom
sezruby:strip-jni-release
Aug 7, 2026
Merged

build: strip release cdylib to shrink the JNI native library#8314
Xuanwo merged 1 commit into
lance-format:mainfrom
sezruby:strip-jni-release

Conversation

@sezruby

@sezruby sezruby commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What

Add a [profile.release] to java/lance-jni/Cargo.toml that strips symbols from the release build:

[profile.release]
strip = true

Because java/lance-jni is excluded from the root workspace (see the root Cargo.toml), this profile applies to the crate's release build directly.

Why

The release JNI cdylib currently ships unstripped, retaining the .symtab/.strtab symbol tables. These add tens of MB to the shipped shared library and provide no runtime benefit for the loaded native library.

Measured on linux-x86-64:

liblance_jni.so
before 278.35 MB
after 221.0 MB
delta −57.35 MB (−20.6%)

The removed weight is almost entirely the symbol tables (.symtab ≈ 12.5 MB, .strtab ≈ 44.8 MB); the release build already emits no DWARF (.debug_* sections are absent).

Why this is safe

strip = true removes .symtab/.strtab (the regular symbol tables) but preserves the dynamic symbol table (.dynsym). The JVM resolves native methods through .dynsym, so every exported Java_* symbol is retained and native-method lookup is unaffected — verified that all Java_* exports remain resolvable (nm -D) after stripping. Only unused symbol metadata is dropped; code and data are untouched.

Consistency with existing profiles

This aligns the Java release artifact with how the project already treats shipped vs. debuggable builds:

  • Python release wheels are already built with maturin --strip (full strip) in .github/workflows/pypi-publish.yml — the Java JNI cdylib simply never got the equivalent.
  • [profile.bench] sets strip = false (keep symbols where you profile); dev/ci use strip = \"debuginfo\". Stripping the release JNI artifact is the missing counterpart.
  • Reducing binary size is a stated goal (Reduce binary size #2224).

Debuggability trade-off (considered)

After stripping, a native crash backtrace shows raw addresses rather than function names. In practice the release build already emits no DWARF, so even today it yields function names only (from .symtab), never line numbers — the same trade-off the Python wheels already accept.

If out-of-band symbolication is later desired, the clean path is split debug info rather than shipping the symbol tables in every artifact: set debug = \"line-tables-only\" + split-debuginfo = \"packed\" + strip = \"symbols\", which produces an identically-sized stripped .so plus a separate .dwp to archive. That is a build-pipeline change (it needs debug enabled and somewhere to store the .dwp), so it is out of scope here; this PR keeps the minimal, zero-infra strip = true.

The release JNI cdylib currently ships unstripped, retaining the
.symtab/.strtab symbol tables (~57 MB on linux-x86-64). strip = true
removes them. JNI method resolution uses the dynamic symbol table
(.dynsym), which strip preserves -- all exported Java_* symbols remain,
so this is functionally safe. Measured on linux-x86-64: liblance_jni.so
278.35 MB -> 221.0 MB (-57.35 MB, -20.6%). Because java/lance-jni is
excluded from the root workspace, this profile applies to the crate
build directly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added chore A-java Java bindings + JNI labels Aug 6, 2026

@lance-gatekeeper lance-gatekeeper Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gate recommendation: approve.

The standalone release profile applies to both published Linux and macOS builds, and Cargo’s symbol stripping preserves the dynamic export table used by JNI. Keeping the policy in Cargo is simpler and less drift-prone than platform-specific post-link stripping.

@Xuanwo
Xuanwo merged commit 3189e0d into lance-format:main Aug 7, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-java Java bindings + JNI chore

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants