java-native-access/jna · error · HeadlessException
KeyboardUtils requires a keyboard
Error message
KeyboardUtils requires a keyboard
What it means
KeyboardUtils' static initializer throws HeadlessException if the JVM reports a headless graphics environment, since the keyboard utilities need a real keyboard/display context. Class initialization fails and INSTANCE is never created.
Source
Thrown at contrib/platform/src/com/sun/jna/platform/KeyboardUtils.java:49
import com.sun.jna.platform.unix.X11;
import com.sun.jna.platform.unix.X11.Display;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinUser;
/** Provide access to the local keyboard state. Note that this is meaningless
* on a headless system and some VNC setups.
*
* @author twall
*/
// TODO: key clicks
// TODO: auto-repeat
// TODO: keyboard bell
// TODO: led state
public class KeyboardUtils {
static final NativeKeyboardUtils INSTANCE;
static {
if (GraphicsEnvironment.isHeadless()) {
throw new HeadlessException("KeyboardUtils requires a keyboard");
}
if (Platform.isWindows()) {
INSTANCE = new W32KeyboardUtils();
}
else if (Platform.isMac()) {
INSTANCE = new MacKeyboardUtils();
throw new UnsupportedOperationException("No support (yet) for "
+ System.getProperty("os.name"));
}
else {
INSTANCE = new X11KeyboardUtils();
}
}
public static boolean isPressed(int keycode, int location) {
return INSTANCE.isPressed(keycode, location);
}
public static boolean isPressed(int keycode) {View on GitHub (pinned to d036ad9781)
Solutions
- Run with a display available and java.awt.headless=false (use Xvfb on servers)
- Guard KeyboardUtils usage with !GraphicsEnvironment.isHeadless() checks
- Use a non-GUI input mechanism (e.g. JLine or native console reading) in headless environments
Example fix
// before
boolean pressed = KeyboardUtils.isPressed(KeyEvent.VK_SHIFT);
// after
if (GraphicsEnvironment.isHeadless()) {
throw new IllegalStateException("KeyboardUtils requires a non-headless environment");
}
boolean pressed = KeyboardUtils.isPressed(KeyEvent.VK_SHIFT); Defensive patterns
Strategy: validation
Validate before calling
if (GraphicsEnvironment.isHeadless()) {
throw new IllegalStateException("KeyboardUtils requires a display (non-headless JVM)");
} Type guard
boolean keyboardUtilsAvailable() {
return !GraphicsEnvironment.isHeadless();
} Try / catch
try {
KeyboardUtils.isPressed(keycode);
} catch (HeadlessException | ExceptionInInitializerError e) {
logger.warn("No keyboard available in this environment");
} Prevention
- Do not set java.awt.headless=true in apps using KeyboardUtils
- Provide a virtual display (Xvfb) on servers/CI
- Check isHeadless() before initializing keyboard features
When it happens
Trigger: Referencing KeyboardUtils (any static method like isPressed) while running with -Djava.awt.headless=true, or on a machine without display/input devices (servers, containers).
Common situations: CI pipelines and headless servers running key-listening code; Docker containers without X11; java.awt.headless explicitly set true in build/test configs.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- No support (yet) for " + System.getProperty("os.name")
- Can't open X Display
- No native windows when headless
- FileMonitor not implemented for " + os
- No trash location found (define fileutils.trash to be the pa
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/c3df4702090af152.
Report an issue: GitHub.