Repository navigation
Add an independent Java adapter - #24
Merged
Merged
Conversation
A Maven project in java/ (org.jacquardlang:jacquard-host, Java 21+, no runtime dependencies) implementing jacquard-host-v0: strict codecs, the session state machine, a bounded process carrier for `jacquard host worker`, a Host with a closed operation registry, and replay of the pinned conformance kit, carried as class-path resources. Java cannot start the worker in its own process group and cannot interrupt a pipe read. The carrier therefore reads stdout and stderr only after available() reports bytes, on the caller's thread, rechecking the lifetime deadline, cancellation, and the interrupt status in every wait; writes run on one stdin thread in gated 4096-byte chunks; and expiry kills a ProcessHandle snapshot of the worker's process tree. What that misses is documented in java/README.md. core_pin.py generates Compat.java and keeps the Java kit copy in sync. NOTICE names the new copy, java/NOTICE stays identical to it, and the source archive carries the Java project.
A java job runs the offline tests on Java 21 and 25, and the shared pinned-Core job runs the live tests on Java 21 with JACQUARD_REQUIRE_LIVE set, so a misconfigured job fails rather than skips.
LIMITS.md records the process-tree kill, what the JDK's own reaping and pipe handling hide, the uninterruptible stdin write, cooperative handler cancellation, and the protocol-level scope. EVIDENCE.md records the offline and live results on Java 21 and 25 against jacquard-core-0.3.0.
Process.destroyForcibly() closes the worker's stdin on the calling thread, which waits behind a write the stdin thread has blocked on a pipe a child holds; the kill never reached the child. Signal the worker through its ProcessHandle instead. Regression tests keep the worker alive at expiry and at cancellation. Refuse null arguments before a worker starts, bound the live fixture install, extend the leak checks to failure paths, and correct the docs on in-flight chunks, retained threads, and worst-case cleanup.
The JDK drains a process's output pipes on its reaper thread when the process exits, under the stream lock available() and close() also take, into an unbounded buffer, for as long as a descendant keeps writing. A reparented descendant flooding stdout or stderr held the caller for seconds past the deadline and grew the heap by hundreds of MiB. On Unix the host now creates both pipes as FIFOs with mkfifo in a private directory, holds their read ends, and redirects the worker's output to them, so no host read waits on a JDK lock and a flood stays in the pipe until disposal closes it. Regression tests flood stderr at the worker's exit, at expiry, and at cancellation, and flood stdout.
jbwinters
force-pushed
the
task/java-adapter
branch
from
October 27, 2026 22:22
8be788e to
c262953
Compare
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Adds an independent Java 21 implementation of Core's pinned
jacquard-host-v0protocol injava/: strict JSON and v0 value codecs, the host session state machine, a bounded process carrier forjacquard host worker, a low-levelHostwith a closed operation registry, and a replayer for the pinned conformance kit. It has no third-party runtime dependencies (JUnit 5 at test scope only), builds with Maven, and on Unix runs the systemmkfifo.java/src/main/resources, tracked byscripts/core_pin.py, which also generatesCompat.java.live-examplesruns the live suite against the pinned Core with live tests required (65 tests, none skipped).Java differs from the other adapters in ways
docs/LIMITS.mdandjava/README.mdrecord:ProcessHandle, so a blocked stdin write cannot hold the kill). A descendant that was already reparented survives.available()on the caller's thread.Every wait, and FIFO setup, observes the one lifetime deadline, the
Cancel, and the caller's interrupt. Frame encoding stops atmax_frame_bytes, and text validation is charged against the frame. No handler starts once the call is cancelled, interrupted, or past its lifetime. Kit replay keeps at most one frame beyond the recording. Each of these has a regression test that fails on the code before it; seedocs/EVIDENCE.md.The SDK layer follows in a separate PR.