linliu-code opened a new pull request, #783: URL: https://github.com/apache/hudi-rs/pull/783
## What this is Position **4 of 4** in a series porting work from Onehouse's `hudi-rs` fork onto upstream `main`. The series is linear and must land in order: **01 → 02 → 03 → 04**. **Draft** — this cannot merge until #780 and any earlier position land. A PR to `apache/hudi-rs` must be based on a branch in this repository, so the series cannot be stacked on GitHub. This branch therefore carries the earlier positions' commits too, and the "Files changed" view is cumulative. **The work unique to this PR is 22 commits, `1c6e09c6..baa08e02`** — please review those. ## What it does Exports a `reader_v2` file-group read to the JVM as an **Arrow C stream**, plus `libhudi_jni.so` as the carrier. - `crates/jvm-ffi/` — builds the reader, performs the read, and hands back an `FFI_ArrowArrayStream`. - `crates/jni/` — the JNI entry points (`readFileGroupInto`, `version`). ## Memory and panic safety This is the part worth a careful pass, so here is what has already been checked: - **Every new `extern "C"` entry point is `catch_unwind`-guarded.** A Rust panic unwinding into the JVM is undefined behaviour; all three are wrapped and convert a panic into a thrown `NativeReaderException` or an error return. - **The Arrow C Data Interface contract holds.** `release` is always set, is reclaimed exactly once and is idempotent; `private_data` is deliberately leaked in `new` and reclaimed in `release`. `out_stream` is null-checked before the read and the `ptr::write` is the last statement, so the caller's struct is untouched on every error path. - **JNI local references are bounded** — each element read runs inside a `with_local_frame`, which pops on both the success and the error path. `throw` checks for a pending exception before raising a second. ## Known - **arrow-rs's own stream callbacks are unguarded.** `get_schema` / `get_next` / `get_last_error` / `release_stream` carry no `catch_unwind`. This is safe here only because the read is fully materialised into one `RecordBatch` *before* the stream is constructed, so all panic-capable decode happens inside the guarded entry point. That property is load-bearing; a lazy variant would need a per-`next()` guard. - **`crates/jni` has no tests in-repo** — it is `crate-type = ["cdylib"]`, so `cargo test` compiles it and runs nothing. It is exercised by a JVM consumer outside this repository. Inert by design rather than by accident, but worth knowing. - The reader context is built with several fields hardcoded, which suits the metadata table but is not obvious from the export's general-sounding name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
