kotlin-polycall
v1.0.0
Published
Kotlin/JVM binding for the Polycall binding ABI v1 (Foreign Function & Memory API, JDK 22+). Source distribution of a Gradle project; not a JavaScript library.
Maintainers
Readme
kotlin-polycall
Kotlin/JVM binding for the Polycall
core library, binding ABI v1 (polycall.h, documented in the core's
docs/BINDING_ABI.md).
The binding calls polycall.dll (Windows, MSVC build), libpolycall.dll
(MinGW) or libpolycall.so.1 (Linux) directly through the Java Foreign
Function & Memory API (java.lang.foreign, JDK 22+). There is no JNI shim and
no C code to compile.
Requirements
- JDK 22 or newer (tested with JDK 25 on Linux and Windows, JDK 27 on Windows)
- Kotlin 2.4 via Gradle 8.10+ (tested with Gradle 9.7 / 9.8)
- libpolycall >= 1.1.0 (binding ABI 1), 64-bit
Loading the library
POLYCALL_LIBRARY (full path) first, then the polycall.library system
property, then polycall.dll / libpolycall.dll (Windows), libpolycall.so.1
(Linux), libpolycall.1.dylib (macOS) through the OS search. Every symbol is
resolved up front and polycall_ffi_abi_version() must be 1; otherwise a
PolycallLoadException names the library and the problem. Run the JVM with
--enable-native-access=ALL-UNNAMED.
API
import org.obinexus.polycall.Peer
import org.obinexus.polycall.Polycall
val status = Polycall.runConfig("kotlin-polycallrc") // polycall_ffi_run_config(path, 1), unchanged status
Polycall.runConfigOrThrow("kotlin-polycallrc") // PolycallException(status, statusName, detail)
Polycall.runConfigOrThrow(path, strict = false) // validate only
Polycall.describe(path)
Polycall.call("127.0.0.1:7000", "inventory", "get", """{"item_id":"widget-a"}""", 2000)
Peer.open("alpha", "127.0.0.1:0", token).use { alpha ->
Peer.open("beta", "127.0.0.1:0", token).use { beta ->
alpha.register("beta", beta.endpoint)
alpha.send("beta", bytes, "msg-1", 5000) // exactly one delivery attempt
val m = beta.recv(5000) // m.sender, m.messageId, m.payload
}
}Peer covers open / close / endpoint / nodeId / register / unregister / list /
ping / send / recv / tryRecv / cancel / health; it is thread-safe, close() is
idempotent and wakes blocked receivers. See examples/Main.kt.
Tests
POLYCALL_LIBRARY=/opt/polycall/lib/libpolycall.so.1 \
POLYCALL_CLI=/opt/polycall/bin/polycall sh scripts/test.sh # or: gradle testThe JUnit 5 suite runs against the real library and the real polycall CLI:
version/ABI, run_config (valid, missing, invalid, strict, TLS, a non-ASCII
directory and file name), call against polycall start and polycall daemon
start, two-node exchange both ways with empty/UTF-8/binary/1 MiB/1 MiB+1
payloads, registry ownership, duplicates, auth, dead peer, timeouts,
too-small buffers, cancel/close, invalid handles, a dropped peer closed by its
Cleaner, out-of-range uint32_t timeouts, concurrent senders and calls, and
interop with polycall peer serve/send/recv/health/register. With
POLYCALL_INTEROP_ECHO naming another binding's echo agent (java-polycall or
fsharp-polycall peer echo) it also exchanges payloads with that binding.
Checks that cannot run are reported as skipped, never passed;
scripts/test.sh exits 77 when JDK 22+ or Gradle is missing.
Loader errors are checked in-process and in a fresh JVM (LoaderProcessTest:
PolycallLoadException naming the library, no crash): a missing file, a
library without the binding ABI, a real 1.0 core when
POLYCALL_TEST_V1_0_LIBRARY names one (libpolycall built from polycall
v1.0.0), and an ABI-2 library when POLYCALL_TEST_FAKE_ABI2 names one.
src/test/c/fake_polycall_abi2.c is that clearly-labelled fake library
(scripts/test.sh builds it when a C compiler is present); it is used only
for the loader's ABI-mismatch test.
On Windows, run gradle test with POLYCALL_LIBRARY set to polycall.dll
(MSVC build) or libpolycall.dll (MSYS2 UCRT64 build) and POLYCALL_CLI to
the matching polycall.exe. -PtestJavaVersion=N runs the tests on another
installed JDK than the one running Gradle. A JVM runs in the ANSI code page,
so non-ASCII configuration paths need a core that opens files by UTF-8 path
(polycall commit 58bae1b or later); older DLLs report POLYCALL_E_NOT_FOUND.
Packaging
The Maven publication org.obinexus:kotlin-polycall (jar, sources jar, POM
with the Kotlin standard library as its only runtime dependency) can be built
into a directory inside build/ -- nothing is uploaded:
gradle publishMavenPublicationToBuildRepoRepository # -> build/repoThe npm package is a source distribution: require('kotlin-polycall')
returns the paths of the packaged sources and manifests.
Author and license
Copyright © 2026 Nnamdi Michael Okpala [email protected]. Released under the MIT License.
