{"record":{"id":"132aed6928c429e1","repo":"java-native-access/jna","slug":"can-t-determine-class-with-native-methods-from-the-current","errorCode":null,"errorMessage":"Can't determine class with native methods from the current context (cls)","messagePattern":"Can't determine class with native methods from the current context \\(cls\\)","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Native.java","lineNumber":1588,"sourceCode":"\n    /** Find the nearest enclosing class with native methods. */\n    static Class<?> findDirectMappedClass(Class<?> cls) {\n        Method[] methods = cls.getDeclaredMethods();\n        for (Method m : methods) {\n            if ((m.getModifiers() & Modifier.NATIVE) != 0) {\n                return cls;\n            }\n        }\n        int idx = cls.getName().lastIndexOf(\"$\");\n        if (idx != -1) {\n            String name = cls.getName().substring(0, idx);\n            try {\n                return findDirectMappedClass(Class.forName(name, true, cls.getClassLoader()));\n            } catch(ClassNotFoundException e) {\n                // ignored\n            }\n        }\n        throw new IllegalArgumentException(\"Can't determine class with native methods from the current context (\" + cls + \")\");\n    }\n\n    /** Try to determine the class context in which a {@link #register(String)} call\n        was made.\n    */\n    static Class<?> getCallingClass() {\n        // This method makes the assumption that it is only called from register\n        // and unregister methods of this class. It is further assumed, that\n        // these two methods are called from a static initialized block or from\n        // a method of the class to be registered.\n        //\n        // There are two approaches taken to find the right stack frame:\n        // - on modern VMs the StackWalker API is used and the first two entries\n        //   are skipped. The stack at the time of calling is:\n        //   0. Stackframe: #getCallingClass\n        //   1. Stackframe: #register or #unregister\n        //   2. Stackframe: method of outer caller\n        //   the last element is the right one","sourceCodeStart":1570,"sourceCodeEnd":1606,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Native.java#L1570-L1606","documentation":"Native.register() can infer the class containing native method declarations from the call stack when it is not passed explicitly. After trying the caller-class and ClassLoader-resource heuristics, JNA gives up when no class with native methods can be determined from the current context, and throws this IllegalArgumentException mentioning the (null or wrong) cls it found.","triggerScenarios":"Calling Native.register() with no explicit Class argument from code that is not a static initializer of the interface/implementation class — e.g. from a helper method, factory, lambda, reflection frame, or a relocated/obfuscated stack where the inferred class has no native methods.","commonSituations":"Registering in a non-standard bootstrap path (Spring bean factory method, OSGi bundle classloader, GraalVM native-image with stripped stacks), or calling register indirectly so the 'cls' heuristic resolves to the wrong class.","solutions":["Pass the class explicitly: Native.register(MyLib.class) (or Native.register(libName, MyLib.class)) instead of relying on inference.","Move the Native.register call into the static initializer of the class that declares the native methods.","If using obfuscation/minification (ProGuard/R8), keep the registering class name and its native methods.","Use the overload taking a NativeLibrary instance with an explicit class to bypass stack inspection entirely."],"exampleFix":"// before\nstatic void init() { Native.register(); } // inferred context is wrong/null\n\n// after\nstatic void init() { Native.register(MyNativeLib.class); }","handlingStrategy":"validation","validationCode":"if (cls == null || cls.getDeclaredMethods().length == 0) {\n    throw new IllegalArgumentException(\"Native.register needs an explicit class that declares native methods\");\n}\nNative.register(cls);","typeGuard":null,"tryCatchPattern":"try {\n    Native.register();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Can't determine class\")) {\n        Native.register(MyNativeLib.class);\n    } else { throw e; }\n}","preventionTips":["Always use the explicit overload Native.register(Class) or Native.register(String, Class).","Only use the no-arg inference form directly inside a static initializer of the mapped class.","Configure obfuscators (ProGuard/R8) to keep classes that call Native.register.","Avoid calling register from helper/factory methods that break stack inference."],"tags":["jna","register","classloader","stack-inspection"],"backgroundTag":"missing-required-argument","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"}