Skip to content

Use receiver-style zenoh-flat-jni bindings#481

Merged
milyin merged 141 commits into
zenoh-flat-transitionfrom
prebindgen-split-api
Jul 16, 2026
Merged

Use receiver-style zenoh-flat-jni bindings#481
milyin merged 141 commits into
zenoh-flat-transitionfrom
prebindgen-split-api

Conversation

@milyin

@milyin milyin commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • call generated receiver methods instead of package functions that repeated their handle argument
  • use Config.insertJson5, Publisher.put/delete, Querier.get, Query.reply*, and Session operations directly
  • open the native session through the generated Session.open companion factory
  • preserve Rust ownership by cloning Config before open and KeyExpr before consuming declarations
  • retain the regression test that opens multiple sessions from one Config
  • update CI to the linked zenoh-flat-jni commit while resolving prebindgen from GitHub main

Throughput

Release benchmark, subscriber median msg/s across three passes, 8 rounds × 100,000 messages per point:

Payload upstream main flat JNI change
8 B 485,085 869,716 +79.3%
64 B 461,949 847,465 +83.5%
1 KiB 407,366 657,009 +61.3%
8 KiB 223,830 249,825 +11.6%

Baseline: upstream 20622e3. Benchmarked implementation: 834a51c. The later receiver-method update relocates the same generated wrapper bodies and native calls; it does not add work to the hot path.

Validation

Validated locally against prebindgen 616f676 and zenoh-flat-jni d8613fb:

  • composite Kotlin/JNI compilation
  • full 101-test native JVM suite
  • linked JNI Cargo check, clippy, and tests

Depends on:

CI intentionally resolves prebindgen from GitHub main, so the dependency chain must merge in order. This is the coordinated successor to #473.

milyin and others added 30 commits May 23, 2026 17:13
BFS from each required-but-unresolved type through struct fields, enum
variants, generic args, and impl Fn args, surfacing transitively
unresolved entries that propagate_required cannot reach (because subs
edges don't exist past an unresolved parent). Without this, a missing
declaration in build.rs for a type only referenced as a field of another
unresolved struct went unreported.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
.method() is a namespace declaration — every #[prebindgen] fn must
be assigned to a typed handle, data class, enum, or kotlin_package.
There is no third "orphan" bucket, so JNIOrphaned was always emitted
empty and the duplicate declared_function_names helper just repeated
the PrebindgenExt::declared_functions trait method.

- delete write_jni_orphaned, jni_orphaned_class_name, the stale
  generated JNIOrphaned.kt file
- rename render_jni_orphaned_source -> render_jni_package_source,
  drop the now-redundant include_only_promoted / wrap_in_object /
  declared / class_name params
- drop declared_function_names; render_jni_native_source now takes
  &HashSet<syn::Ident> from declared_functions() directly

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the five scattered self.qualify_emitted_type() calls (build_input_fn,
build_output_fn, opaque_handle_input, build_handle_destructor_items,
option_input) with a single AST visitor pass applied once at write time.

The previous design qualified only at specific emit sites — each new emit
site had to remember the call. emit_into_dispatcher missed it, so the
impl-Into dispatcher body emitted bare KeyExpr/ZKeyExpr references that
failed to resolve in the binding crate's scope.

Architecture:
- New PrebindgenExt::post_process_item(item: &mut syn::Item) trait hook
  (default no-op), invoked by write_rust on every emitted item.
- JniExt implements it via qualify_item, which runs QualifyEmittedTypes —
  a syn::visit_mut::VisitMut that walks the full AST (signatures, generic
  args, type ascriptions in let bindings, *mut/*const in cast expressions)
  and prefixes every bare single-segment Type::Path matching a registered
  source-module name with source_module.
- option_input no longer takes &JniExt; the body uses the bare t1 token
  and the post-emit visitor qualifies it later.

Also fixes the pre-existing TypeEntry field-name drift in
final_invariant_reports_unresolved_field_of_unresolved_struct.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
milyin and others added 10 commits June 13, 2026 16:37
…pendency

- Remove :zenoh-flat-jni from gradle subprojects (moved to separate repo)
- Replace local source dependency with Maven: org.eclipse.zenoh:zenoh-flat-jni:1.9.0
- Remove Cargo build orchestration (buildZenohFlatJni, buildZenohFlatJNI, BuildMode)
- Remove build paths for zenoh-flat-jni libraries (now bundled in Maven JAR)
- Remove Cargo-related Gradle plugins and tasks
- Native libraries are now obtained from the zenoh-flat-jni Maven artifact
- Kotlin sources are now imported from the Maven JAR as a dependency
- Supports optional local development via: includeBuild("../zenoh-flat-jni")
- Simplifies zenoh-java build: Gradle now only compiles Kotlin, not Rust

Migration notes:
- zenoh-flat-jni is now at https://github.com/ZettaScaleLabs/zenoh-flat-jni
- Versions will be synchronized with Zenoh releases (1.9.0, etc.)
- For local development, clone both repos and use composite builds if needed

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ment

- Uncomment includeBuild for ../zenoh-flat-jni since it's now in the PREBINDGEN workspace
- zenoh-flat-jni is at /Users/milyin/PREBINDGEN/zenoh-flat-jni
- Gradle will prefer local build over Maven artifact when composite build is enabled
- Allows coordinated development of zenoh-java and zenoh-flat-jni

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The zenoh-flat-jni project has been moved to:
- GitHub: https://github.com/ZettaScaleLabs/zenoh-flat-jni
- Local workspace: /Users/milyin/PREBINDGEN/zenoh-flat-jni

zenoh-java now consumes zenoh-flat-jni via:
1. Maven artifact (org.eclipse.zenoh:zenoh-flat-jni:1.9.0) in production
2. Gradle composite build (../zenoh-flat-jni) for local development

Removing the local copy avoids duplication and confusion.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@milyin

milyin commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Linked generator inputs: ZettaScaleLabs/zenoh-flat#1 and ZettaScaleLabs/zenoh-flat-jni#2.

@milyin milyin changed the title Use typed zenoh-flat-jni KeyExpr overloads Use receiver-style zenoh-flat-jni bindings Jul 15, 2026
zenoh-flat's consolidated API dropped the Z prefix from its Rust types
(ZSample -> Sample, ...), and the generated callback interface names follow
the type name mechanically: ZSampleCallback -> SampleCallback etc. Rename the
four callback references in FlatCallbacks.kt (signatures are unchanged) and
follow the encoding id accessor rename (id -> getId).

Pin CI to the updated zenoh-flat-jni (receiver-style bindings regenerated
against prebindgen main and zenoh-flat main) and to zenoh-flat main.

Verified locally: jvmTest 101 tests, 0 failures against the composite build.
@milyin

milyin commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

Updated to the consolidated upstream stack (commit 8461c29):

  • Callback names track the de-prefixed zenoh-flat types: ZSampleCallbackSampleCallback, ZQueryCallbackQueryCallback, ZReplyCallbackReplyCallback, ZHelloCallbackHelloCallback in FlatCallbacks.kt (signatures unchanged — the generated callback interface name follows the Rust type name, which lost its Z prefix in zenoh-flat's API consolidation). Also Encoding.idgetId.
  • CI pins moved off the prototype branches onto the mainline stack: zenoh-flat-jni → 7b307c9 (Modernize to current prebindgen: receiver-style API, derived names, split overloads ZettaScaleLabs/zenoh-flat-jni#3 — the receiver-style bindings regenerated against prebindgen main), zenoh-flat → 7b151d7 (main, the consolidated flat API).

Validation: composite build compiles; jvmTest 101 tests, 0 failures locally against prebindgen main + zenoh-flat main + zenoh-flat-jni PR #3.

zenoh-flat-jni now derives all regular method names from the flat crate's
identifiers (explicit .name() only where a clash forces it), so the internal
calls follow: JniKeyExpr.newTryFrom/newAutocanonize/newJoin/newConcat,
JniConfig.newFrom*, JniEncoding.newFromString/newWithSchema,
JniZBytes.newFromVec, zSession.getPeersZid/getRoutersZid. SDK public API
unchanged. CI pin bumped to the matching zenoh-flat-jni commit.
@milyin milyin changed the base branch from main to zenoh-flat-transition July 16, 2026 11:27
@milyin

milyin commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

Retargeted to the zenoh-flat-transition integration branch — this PR is now the first constituent of the umbrella transition PR #482, which accumulates all zenoh-flat–related work and merges to main as a whole.

@milyin milyin merged commit 94c885a into zenoh-flat-transition Jul 16, 2026
13 checks passed
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.

1 participant