java-native-access/jna · error · java.lang.IllegalStateException

Component must be visible

Error message

Component must be visible

What it means

Thrown by Native.getWindow(Component) on X11 Java 1.4 VMs when the component is not yet visible. In that old environment JNA requires the window to be actually visible before obtaining the native window handle, otherwise AWT/JAWT lookups fail.

Source

Thrown at src/com/sun/jna/Native.java:2554

            return getComponentID(w);
        }
        // Declaring the argument as Object rather than Component avoids class not
        // found errors on phoneME foundation profile.
        static long getComponentID(Object o) throws HeadlessException {
            if (GraphicsEnvironment.isHeadless()) {
                throw new HeadlessException("No native windows when headless");
            }
            Component c = (Component)o;
            if (c.isLightweight()) {
                throw new IllegalArgumentException("Component must be heavyweight");
            }
            if (!c.isDisplayable())
                throw new IllegalStateException("Component must be displayable");
            // On X11 VMs prior to 1.5, the window must be visible
            if (Platform.isX11()
                && System.getProperty("java.version").startsWith("1.4")) {
                if (!c.isVisible()) {
                    throw new IllegalStateException("Component must be visible");
                }
            }
            // By this point, we're certain that Toolkit.loadLibraries() has
            // been called, thus avoiding AWT/JAWT link errors
            // (see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6539705).
            return Native.getWindowHandle0(c);
        }
    }
}

View on GitHub (pinned to d036ad9781)

Solutions

  1. Call frame.setVisible(true) before Native.getWindow(c)
  2. Upgrade the JVM; this restriction only applies to 1.4-era X11 VMs
  3. Guard the call with if (c.isVisible())

Example fix

// before
long hwnd = Native.getWindow(frame);
// after
frame.setVisible(true);
long hwnd = Native.getWindow(frame);
Defensive patterns

Strategy: validation

Validate before calling

if (Platform.isX11() && c != null && !c.isVisible()) {
    frame.setVisible(true); // or defer the call
}
long hwnd = Native.getWindow(c);

Prevention

When it happens

Trigger: Calling Native.getWindow(c) on X11 with java.version starting with '1.4' while c.isVisible() is false (e.g. before setVisible(true) or while the frame is hidden).

Common situations: Legacy deployments on old X11 JVMs where automation scripts fetch window handles immediately after creating the frame without making it visible.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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