Repository navigation
feat(bindings): a Java binding over the C API - #575
Closed
aditipolkam wants to merge 7 commits into
Closed
aditipolkam wants to merge 7 commits into
aditipolkam wants to merge 7 commits into
Conversation
The binding is a JVM wrapper over the C API through JNA, so the build has no native step: it loads the library the desktop releases already ship. Java 11 or later, javac warnings are errors, and the tests take the library directory from -PnativeLibraryDir (default: this checkout's Cargo debug output).
… types NativeApi declares the functions, structures and callback signatures of offline_protocol.h. Strings the library hands out are read as UTF-8 and released only with offline_protocol_string_free, never copied by JNA and left to leak, and every string in is UTF-8 whatever the JVM's default charset is. size_t is a long, so a 32-bit JVM is refused at load time rather than corrupting memory. OfflineProtocolException carries the status, the ProtocolError variant and its position.
…d transport notifications Methods are called by their local API name with a JSON object, so the class does not change when the definition grows a method and takes no JSON library of its own. Event and transport listeners reach the library through static callback singletons and an id in ctx, which keeps every JNA callback reachable and lets the library's single drop(ctx) be the only place a registration is released, refused ones included. close() takes the write side of a lock the calls share, which is the contract's no call in flight when the engine is freed. A listener's exception is swallowed rather than unwound into Rust.
…rmance suite StorageProvider is the four operations of the C provider as a Java interface. A buffer handed back to the library is native memory held until the library returns it through release, and an exception that is not the provider's own StorageException is reported as the operation's failure, never as corruption, which would make the engine mint a new protocol-state key and strand every record sealed under the old one. OfflineProtocol.initializeMls attaches two providers and runStorageConformance runs the suite against one.
The counterpart of bindings/c/consumer-check/main.c, run by Gradle against the Cargo build: the version and an instance-less call, events on the calling thread and in the poll queue, every refusal status and the definition's variant and position, a closed engine, drop(ctx) releasing each listener registration (replaced ones and freed engines), a listener that throws, a Java storage provider passing the conformance suite and giving the engine an address with every buffer returned through release, and the built-in file stores.
…he binding on Linux and macOS HeaderDriftTest reads the committed header: every function in it is declared in NativeApi and nothing else is, and the Status, Transport and storage Kind values are the header's numbers. A function added to the header and not declared here is unreachable from Java and fails no build. The java-binding job builds the library, then compiles with -Xlint:all -Werror, runs the consumer check and builds the Javadoc and sources jars.
…in the docs bindings/java/README.md is the guide: what to load and how the JVM finds it, a quick start, how methods are named and encoded, events, storage and the build. docs/bridges/java.md is the contract: it is the C binding with Java types, which shared rules reach it and how, why the declarations are held to the header by a test, why a registration is released only by the library's drop, and why a listener cannot close the engine. The binding gets its row wherever the others have one: the docs index, the bridge contract's table, the README's install table, CLAUDE.md's knowledge table and commands, and the CHANGELOG.
|
I have read the CLA Document and I hereby sign the CLA You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
bindings/java: a JNA wrapper over the C API for the JVM on desktop and server (Java 11+, 64-bit). It is the local API called in process, so it parses no JSON and a method added to the interface definition needs no change here.OfflineProtocol(AutoCloseable):create,call/callStaticby local API method name, event and transport listeners,pollEvent,initializeMlswith a JavaStorageProvider, andrunStorageConformance.OfflineProtocolExceptioncarries the status and the definition'sProtocolErrorvariant and position.ctx; a registration is released only by the library'sdrop(ctx).close()waits for calls in flight, matching the C contract.-Djna.library.pathor-Doffline_protocol.library.Contract:
docs/bridges/java.md. Guide:bindings/java/README.md.Tests
ConsumerCheckTest(12 tests) loads the real library, the counterpart ofbindings/c/consumer-check/main.c.HeaderDriftTest(2 tests) fails if the JNA declarations or theStatus,Transportand storageKindvalues drift from the committed C header.java-bindingCI job on Linux and macOS (compiles with-Xlint:all -Werror, runs the tests, builds the Javadoc and sources jars).Run locally on macOS, JDK 17, Gradle 9.3.1:
gradle buildpasses, 14 tests. The CI job has not run yet, and CI pins Gradle 8.9, which I did not try.Not in this PR
🤖 Generated with Claude Code