Experimental signal backends for beckon
use only the Java Foreign Function & Memory API (JDK 22+). Use them as an
alternative to beckon's default sun.misc.Signal backend:
signalfd(2)kqueue(2) with EVFILT_SIGNALsun.misc.Signal is an internal JDK API. The JDK can remove it. This library
tests a supported replacement. It is experimental and ships separately
because it requires JDK 22+. The beckon core jar targets JDK 8.
Use beckon by default. Add
beckon-ffm only when you want the experimental Foreign Function & Memory
backend and can run on JDK 22+.
Add both artifacts, then opt in with a system property.
net.clojars.savya/beckon {:mvn/version "0.4.2"}
net.clojars.savya/beckon-ffm {:mvn/version "0.2.0"}
Leiningen:
[net.clojars.savya/beckon "0.4.2"]
[net.clojars.savya/beckon-ffm "0.2.0"]
Run the JVM with:
-Dbeckon.signal.backend=ffm --enable-native-access=ALL-UNNAMED
The platform selects the native mechanism automatically. The beckon API does not change. See the beckon README.
For Linux service-manager or kill delivery, launch the JVM through the
provided pre-launch shim. It blocks the selected signals before the JVM starts,
so every JVM thread inherits the mask:
clojure -T:build compile-native-shim
target/beckon-signal-launcher --signals TERM,HUP -- \
java -Xrs --enable-native-access=ALL-UNNAMED \
-Dbeckon.signal.backend=ffm -jar app.jar
The allowlist is explicit and narrow. Supported names are HUP, INT,
QUIT, TERM, USR1, USR2, CHLD, CONT, TSTP, and WINCH (subject
to platform availability). USR2 is reserved by HotSpot and CHLD affects
child-process handling; both are rejected by default. The launcher's
--allow-unsafe-signals override is intentionally explicit and emits a clear
warning from its failure-policy message; use it only after reviewing the
impact. The Java backend rejects registrations outside the launcher's
allowlist and verifies /proc/self/status SigBlk at startup.
-Xrs is required for TERM, INT, and HUP: it tells HotSpot not to install
its signal handlers for those signals or alter their handling. See HotSpot's
-Xrs option documentation
and signal chaining.
This mode is opt-in and does not change the default backend. Without the
shim, Linux signalfd remains reliable for beckon's own raise!, but external
process-directed signals are not guaranteed to reach the dispatcher because
the JVM may have created threads before beckon loads. The default backend and
existing non-shim behavior are otherwise unchanged.
The two implementations differ:
signalfd) reliably handles beckon's own raise!. It does not
reliably handle signals from outside the process (e.g. kill -HUP). A JVM
starts threads before beckon loads. signalfd only captures a signal blocked
in every thread. beckon cannot arrange this after the JVM starts.kqueue) sets each managed signal to SIG_IGN. This is a
process-wide disposition. It also observes external signals.The Linux limitation and JEP 472 native-access restrictions mean this is not a
drop-in replacement. --enable-native-access is denied by default from JDK 26.
sun.misc.Signal remains beckon's default.
Requires JDK 22 or later (Foreign Function & Memory API, JEP 454). Linux and macOS/BSD only. CI compiles and tests on JDK 22.
Use JDK 22. Compile the two Java FFM backends before running the test suite:
clojure -T:build compile-java
clojure -T:build compile-native-shim
clojure -M:test
clojure -T:build jar
Copyright © 2026 Savyasachi.
A companion to beckon (originally by Jean Niklas L'orange). Distributed under the Eclipse Public License 1.0.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |