diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c2122f30..d28833d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@v4 with: repository: ZettaScaleLabs/zenoh-flat-jni - ref: e8023170c0be3d8e5cd2cee17487870b27af6728 + ref: 1e040c96d0729c387d411a2356f361e9ea420877 path: zenoh-flat-jni - name: Check out zenoh-flat diff --git a/zenoh-java/src/commonMain/kotlin/io/zenoh/FlatCallbacks.kt b/zenoh-java/src/commonMain/kotlin/io/zenoh/FlatCallbacks.kt index 94741393..c8581fbe 100644 --- a/zenoh-java/src/commonMain/kotlin/io/zenoh/FlatCallbacks.kt +++ b/zenoh-java/src/commonMain/kotlin/io/zenoh/FlatCallbacks.kt @@ -66,7 +66,7 @@ internal fun replyCallbackOf( if (isOk) { Reply.Success( replierId, - Sample.fromParts(keH!!, payloadH!!, encId!!, encSchema, encH!!, kindInt!!, ntp64, express!!, prioInt!!, ccInt!!, attachH, reliabilityInt!!, sourceZid, sourceEid!!, sourceSn!!) + Sample.fromParts(keH!!, payloadH!!, encId!!, encSchema, encH, kindInt!!, ntp64, express!!, prioInt!!, ccInt!!, attachH, reliabilityInt!!, sourceZid, sourceEid!!, sourceSn!!) ) } else { Reply.Error( diff --git a/zenoh-java/src/commonMain/kotlin/io/zenoh/sample/Sample.kt b/zenoh-java/src/commonMain/kotlin/io/zenoh/sample/Sample.kt index 78edc600..e3cc70a4 100644 --- a/zenoh-java/src/commonMain/kotlin/io/zenoh/sample/Sample.kt +++ b/zenoh-java/src/commonMain/kotlin/io/zenoh/sample/Sample.kt @@ -59,7 +59,9 @@ data class Sample( * callbacks), in record order. The whole graph arrives in ONE JNI * crossing; the [KeyExpr] retains the delivered handle leaf, and the * [Encoding] retains its delivered handle (`encH`) so re-sending it - * crosses a bare `jlong` instead of rebuilding the native value. The + * crosses a bare `jlong` instead of rebuilding the native value — + * delivered ONLY for schema-carrying encodings (a preset re-sends + * through the id arm for free, so it arrives value-only). The * trailing `reliability` / `source*` leaves are part of the generated * decomposition but are not surfaced on the public [Sample] type. */ @@ -69,7 +71,7 @@ data class Sample( payloadH: io.zenoh.jni.bytes.ZBytes, encId: Int, encSchema: String?, - encH: io.zenoh.jni.bytes.Encoding, + encH: io.zenoh.jni.bytes.Encoding?, kindInt: Int, ntp64: Long?, express: Boolean, diff --git a/zenoh-java/src/jvmTest/kotlin/io/zenoh/EncodingHandleTest.kt b/zenoh-java/src/jvmTest/kotlin/io/zenoh/EncodingHandleTest.kt index d7685186..ac835c0e 100644 --- a/zenoh-java/src/jvmTest/kotlin/io/zenoh/EncodingHandleTest.kt +++ b/zenoh-java/src/jvmTest/kotlin/io/zenoh/EncodingHandleTest.kt @@ -33,9 +33,11 @@ import org.junit.Test * the send call itself, no handle ever exists; * - custom (schema-carrying) encodings own a handle from construction — * construction is the one crossing, every send after is a bare jlong; - * - received encodings arrive WITH their handle in the same delivery - * crossing, so re-sending one (the save-and-republish scenario) never - * rebuilds the native value from its schema string. + * - received SCHEMA-CARRYING encodings arrive WITH their handle in the same + * delivery crossing, so re-sending one (the save-and-republish scenario) + * never rebuilds the native value from its schema string; a received + * PRESET arrives value-only — its handle would buy nothing (the id arm is + * free), so the binding never materializes one (`encoding_if_schema`). */ class EncodingHandleTest { @@ -95,7 +97,7 @@ class EncodingHandleTest { } @Test - fun predefinedRoundTripStaysValueOnSendAndHandleOnReceive() { + fun predefinedRoundTripStaysValueOnlyEndToEnd() { val session = Zenoh.open(Config.loadDefault()) val keyExpr = KeyExpr.tryFrom("example/testing/encoding/preset") val received = mutableListOf() @@ -110,8 +112,10 @@ class EncodingHandleTest { assertNull(Encoding.TEXT_PLAIN.handle) assertEquals(1, received.size) assertEquals(Encoding.TEXT_PLAIN, received[0].encoding) - // …while the received copy arrived send-ready. - assertNotNull(received[0].encoding.handle) + // …and the received copy is value-only too: a schema-less encoding + // re-sends through the id arm for free, so no per-message native + // handle (clone + Box + wrapper + Cleaner) is ever materialized. + assertNull(received[0].encoding.handle) subscriber.close() session.close()