java-native-access/jna · error · Error

Can't open X Display

Error message

Can't open X Display

What it means

X11KeyboardUtils.isPressed throws Error when XOpenDisplay(null) returns null, meaning no X display connection can be established. The native X11 library is required to query the keymap, so without a display the check cannot proceed.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/KeyboardUtils.java:157

                return X11.XK_Control_L;
            }
            if (code == KeyEvent.VK_ALT) {
                if ((location & KeyEvent.KEY_LOCATION_RIGHT) != 0)
                    return X11.XK_Alt_R;
                return X11.XK_Alt_L;
            }
            if (code == KeyEvent.VK_META) {
                if ((location & KeyEvent.KEY_LOCATION_RIGHT) != 0)
                    return X11.XK_Meta_R;
                return X11.XK_Meta_L;
            }
            return 0;
        }
        public boolean isPressed(int keycode, int location) {
            X11 lib = X11.INSTANCE;
            Display dpy = lib.XOpenDisplay(null);
            if (dpy == null) {
                throw new Error("Can't open X Display");
            }
            try {
                byte[] keys = new byte[32];
                // Ignore the return value
                lib.XQueryKeymap(dpy, keys);
                int keysym = toKeySym(keycode, location);
                for (int code=5;code < 256;code++) {
                    int idx = code / 8;
                    int shift = code % 8;
                    if ((keys[idx] & (1 << shift)) != 0) {
                        int sym = lib.XKeycodeToKeysym(dpy, (byte)code, 0).intValue();
                        if (sym == keysym)
                            return true;
                    }
                }
            }
            finally {
                lib.XCloseDisplay(dpy);

View on GitHub (pinned to d036ad9781)

Solutions

  1. Ensure DISPLAY is set correctly (e.g. export DISPLAY=:0) and the X server accepts connections
  2. Use ssh -X / xhost+ or xauth to grant access when connecting remotely
  3. Run inside an Xvfb virtual display on headless servers; prefer Wayland-native APIs on Wayland

Example fix

// before
boolean pressed = KeyboardUtils.isPressed(code);
// after
if (System.getenv("DISPLAY") == null) {
    throw new IllegalStateException("DISPLAY not set; cannot query X11 keymap");
}
boolean pressed = KeyboardUtils.isPressed(code);
Defensive patterns

Strategy: validation

Validate before calling

if (System.getenv("DISPLAY") == null || System.getenv("DISPLAY").isEmpty()) {
    throw new IllegalStateException("DISPLAY not set; X11 keyboard queries unavailable");
}

Type guard

boolean x11Available() {
    String d = System.getenv("DISPLAY");
    return d != null && !d.isEmpty();
}

Try / catch

try {
    pressed = KeyboardUtils.isPressed(keycode);
} catch (Error e) {
    logger.warn("Cannot open X display: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling KeyboardUtils.isPressed on an X11 (Linux/Unix) system where the DISPLAY environment variable is unset/invalid, the X server is unreachable, or X authorization (xauth) denies the connection.

Common situations: SSH sessions without X forwarding; running inside Docker/systemd services with no DISPLAY; Wayland-only sessions where XOpenDisplay fails.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/101aed27784736ed. Report an issue: GitHub.