{"record":{"id":"bc9c549aff118078","repo":"java-native-access/jna","slug":"neither-the-stackwalker-nor-the-securitymanager-based","errorCode":null,"errorMessage":"Neither the StackWalker, nor the SecurityManager based getCallingClass implementation are useable; you must explicitly provide the class to register","messagePattern":"Neither the StackWalker, nor the SecurityManager based getCallingClass implementation are useable; you must explicitly provide the class to register","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Native.java","lineNumber":1645,"sourceCode":"        if (securityManagerExposerConstructor != null) {\n            Class<?>[] context = null;\n            try {\n                Object securityManagerExposer = securityManagerExposerConstructor.newInstance();\n                context = (Class<?>[]) securityManagerGetClassContext.invoke(securityManagerExposer);\n            } catch (Throwable ex) {\n                LOG.log(Level.WARNING, \"Failed to invoke SecurityManagerExposer#<init> or SecurityManagerExposer#getClassContext\", ex);\n            }\n\n            if (context == null) {\n                throw new IllegalStateException(\"The SecurityManager implementation on this platform is broken; you must explicitly provide the class to register\");\n            }\n            if (context.length < 4) {\n                throw new IllegalStateException(\"This method must be called from the static initializer of a class\");\n            }\n            return context[3];\n        }\n\n        throw new IllegalStateException(\"Neither the StackWalker, nor the SecurityManager based getCallingClass implementation are useable; you must explicitly provide the class to register\");\n    }\n\n    /**\n     * Set a thread initializer for the given callback.\n     * @param cb The callback to invoke\n     * @param initializer The thread initializer indicates desired thread configuration when the\n     * given Callback is invoked on a native thread not yet attached to the VM.\n     */\n    public static void setCallbackThreadInitializer(Callback cb, CallbackThreadInitializer initializer) {\n        CallbackReference.setCallbackThreadInitializer(cb, initializer);\n    }\n\n    private static final Map<Class<?>, long[]> registeredClasses = new WeakHashMap<>();\n    private static final Map<Class<?>, NativeLibrary> registeredLibraries = new WeakHashMap<>();\n\n    private static void unregisterAll() {\n        synchronized(registeredClasses) {\n            for (Map.Entry<Class<?>, long[]> e : registeredClasses.entrySet()) {","sourceCodeStart":1627,"sourceCodeEnd":1663,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Native.java#L1627-L1663","documentation":"Native.register() has two inference strategies: StackWalker (preferred) and the SecurityManager getClassContext fallback. If neither mechanism is available or usable on the runtime — StackWalker cannot produce the caller class and the SecurityManager path failed or was not attempted — JNA throws this final IllegalStateException telling the caller to provide the class explicitly.","triggerScenarios":"Calling Native.register() with no explicit Class on a runtime where both inference paths fail: restricted StackWalker usage, SecurityManager unsupported (modern JDKs), or exotic/embedded JVMs lacking either mechanism.","commonSituations":"JDK 24+ (SecurityManager removed) with an old JNA whose StackWalker fallback also misbehaves, GraalVM native-image with pruned stacks, or sandboxed environments restricting stack access.","solutions":["Always pass the class: Native.register(MyLib.class) or Native.register(libName, MyLib.class) — the explicit overload never uses stack inference.","Upgrade JNA to the latest 5.x release so the StackWalker path works on your JDK.","If you must use inference, register from the static initializer of the declaring class on a JDK with working StackWalker.","Wrap registration in a compatibility check and fall back to the explicit-class form when the runtime is detected as restricted."],"exampleFix":"// before\nstatic { Native.register(\"mylib\"); } // no usable inference on this runtime\n\n// after\nstatic { Native.register(\"mylib\", MyLib.class); }","handlingStrategy":"fallback","validationCode":"boolean stackUsable;\ntry {\n    StackWalker.getInstance().getCallerClass();\n    stackUsable = true;\n} catch (Throwable t) { stackUsable = false; }\nif (!stackUsable) {\n    Native.register(\"mylib\", MyLib.class); // explicit: works everywhere\n}","typeGuard":null,"tryCatchPattern":"try {\n    Native.register(\"mylib\");\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"Neither the StackWalker, nor the SecurityManager\")) {\n        Native.register(\"mylib\", MyLib.class);\n    } else { throw e; }\n}","preventionTips":["Make Native.register(name, Class) the team default; reserve inference for documented static-initializer cases.","Pin a recent JNA version tested against your runtime (JDK 17/21/25, GraalVM native-image).","Add a smoke test that loads every native library at startup on the deployment JDK.","For native-image, provide explicit registration plus reflection/resource configuration."],"tags":["jna","register","stackwalker","jdk-compatibility"],"backgroundTag":"unsupported-platform","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}