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

The SecurityManager implementation on this platform is broke

Error message

The SecurityManager implementation on this platform is broken; you must explicitly provide the class to register

What it means

When register() must infer the calling class and StackWalker is unavailable, JNA installs a SecurityManagerExposer whose getClassContext() supplies the stack classes. If invoking that mechanism throws (or returns null) — i.e. the JVM's SecurityManager machinery is broken or forbidden — JNA cannot determine the class and throws this IllegalStateException.

Source

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

                Object walker = stackWalkerGetInstance.invoke(null, stackWalkerRetainClassReference);
                Class<?> caller = (Class<?>) stackWalkerWalk.invoke(walker, stackWalkerFilter);
                return caller;
            } catch (Throwable ex) {
                LOG.log(Level.WARNING, "Failed to invoke StackWalker#getInstance or StackWalker#walk", ex);
            }
        }

        if (securityManagerExposerConstructor != null) {
            Class<?>[] context = null;
            try {
                Object securityManagerExposer = securityManagerExposerConstructor.newInstance();
                context = (Class<?>[]) securityManagerGetClassContext.invoke(securityManagerExposer);
            } catch (Throwable ex) {
                LOG.log(Level.WARNING, "Failed to invoke SecurityManagerExposer#<init> or SecurityManagerExposer#getClassContext", ex);
            }

            if (context == null) {
                throw new IllegalStateException("The SecurityManager implementation on this platform is broken; you must explicitly provide the class to register");
            }
            if (context.length < 4) {
                throw new IllegalStateException("This method must be called from the static initializer of a class");
            }
            return context[3];
        }

        throw new IllegalStateException("Neither the StackWalker, nor the SecurityManager based getCallingClass implementation are useable; you must explicitly provide the class to register");
    }

    /**
     * Set a thread initializer for the given callback.
     * @param cb The callback to invoke
     * @param initializer The thread initializer indicates desired thread configuration when the
     * given Callback is invoked on a native thread not yet attached to the VM.
     */
    public static void setCallbackThreadInitializer(Callback cb, CallbackThreadInitializer initializer) {
        CallbackReference.setCallbackThreadInitializer(cb, initializer);

View on GitHub (pinned to d036ad9781)

Solutions

  1. Pass the class explicitly: Native.register(MyLib.class) — this avoids class-context inference entirely.
  2. Upgrade/align JNA to a version whose StackWalker-based getCallingClass works on your JDK (5.x+ uses StackWalker first).
  3. Allow SecurityManager usage via -Djava.security.manager=enable if your JDK still supports it (JDK 17 with compatibility flag; removed in 24+).
  4. Move the register call into a static initializer on a supported JDK so the working inference path is used.

Example fix

// before
static { Native.register("mylib"); } // relies on broken SecurityManager inference

// after
static { Native.register("mylib", MyNativeLib.class); }
Defensive patterns

Strategy: try-catch

Validate before calling

boolean smUsable = true;
try { new SecurityManager(); } catch (Throwable t) { smUsable = false; }
if (!smUsable) {
    Native.register("mylib", MyNativeLib.class); // skip inference entirely
} else {
    Native.register("mylib");
}

Try / catch

try {
    Native.register("mylib");
} catch (IllegalStateException e) {
    if (e.getMessage().contains("SecurityManager implementation")) {
        Native.register("mylib", MyNativeLib.class);
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling Native.register() without an explicit class on a JVM/runtime where SecurityManager creation or getClassContext reflection fails — e.g. modern JDKs with SecurityManager disabled (java.security.manager=default disallowed), or JVMs forbidding setSecurityManager.

Common situations: JDK 17+ where the SecurityManager API is unsupported/degraded, containerized runtimes that block installing managers, or custom classloader setups where the reflection call to securityManagerGetClassContext throws.

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


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