Liking cljdoc? Tell your friends :D

beckon-ffm

Clojars Project cljdoc test

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:

  • Linux - signalfd(2)
  • macOS / BSD - kqueue(2) with EVFILT_SIGNAL

sun.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.

Stack

Clojure Java FFM deps.edn tools.build

Installation

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.

Reliable Linux external signals (opt-in)

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.

Capabilities and limits

The two implementations differ:

  • Linux (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.
  • macOS/BSD (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.

Compatibility

Requires JDK 22 or later (Foreign Function & Memory API, JEP 454). Linux and macOS/BSD only. CI compiles and tests on JDK 22.

Development

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

License

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

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close