{"record":{"id":"8640ebd29df18b01","repo":"java-native-access/jna","slug":"lockresource-returned-null","errorCode":null,"errorMessage":"LockResource returned null.","messagePattern":"LockResource returned null\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java","lineNumber":1029,"sourceCode":"                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n            }\n\n            // according to MSDN, on 32 bit Windows or newer, calling FreeResource() is not necessary - and in fact does nothing but return false.\n            HANDLE loaded = Kernel32.INSTANCE.LoadResource(target, hrsrc);\n            if (loaded == null) {\n                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n            }\n\n            length = Kernel32.INSTANCE.SizeofResource(target, hrsrc);\n            if (length == 0) {\n                throw new Win32Exception(Kernel32.INSTANCE.GetLastError());\n            }\n\n            // MSDN: It is not necessary to unlock resources because the system automatically deletes them when the process that created them terminates.\n            // MSDN does not say that LockResource sets GetLastError\n            start = Kernel32.INSTANCE.LockResource(loaded);\n            if (start == null) {\n                throw new IllegalStateException(\"LockResource returned null.\");\n            }\n            // have to capture it into a byte array before you free the library, otherwise bad things happen.\n            results = start.getByteArray(0, length);\n        } catch (Win32Exception we) {\n            err = we;\n        } finally {\n            // from what I can tell on MSDN, the only thing that needs cleanup on this is the HMODULE from LoadLibrary\n            if (target != null) {\n                if (!Kernel32.INSTANCE.FreeLibrary(target)) {\n                    Win32Exception we = new Win32Exception(Kernel32.INSTANCE.GetLastError());\n                    if (err != null) {\n                        we.addSuppressedReflected(err);\n                    }\n                    throw we;\n                }\n            }\n        }\n","sourceCodeStart":1011,"sourceCodeEnd":1047,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java#L1011-L1047","documentation":"Kernel32Util throws this IllegalStateException (not a Win32Exception) when Kernel32.INSTANCE.LockResource returns null after the resource was loaded. MSDN does not document LockResource as setting GetLastError, so JNA signals it as an internal invariant violation instead of a native-error wrapper.","triggerScenarios":"Calling Kernel32Util.getResource(...) where FindResource/LoadResource/SizeofResource all succeeded but LockResource(loaded) returns null — effectively only when the HANDLE passed is invalid, which under normal use cannot happen because it was just returned by LoadResource.","commonSituations":"Very rare in practice: memory pressure or corrupted process state, custom Kernel32 mappings that mishandle HMODULE/HRSRC types, running the extraction logic on a concurrently-unloaded module.","solutions":["Verify no concurrent FreeLibrary/unload invalidates the loaded handle","Check any custom Kernel32 interface mapping returns a proper Pointer for LockResource","Catch IllegalStateException and retry resource extraction once","Report as a JVM/native-level failure if reproducible — the preceding calls succeeded"],"exampleFix":"// before\nbyte[] data = Kernel32Util.getResource(h, type, name); // may throw IllegalStateException\n// after\ntry {\n    byte[] data = Kernel32Util.getResource(h, type, name);\n} catch (IllegalStateException e) {\n    throw new IllegalStateException(\"LockResource failed for resource \" + name + \" in \" + h, e);\n}","handlingStrategy":"try-catch","validationCode":"if (target == null) throw new IllegalArgumentException(\"module handle required\");\n// ensure the module stays loaded: hold a reference and no FreeLibrary in this scope","typeGuard":"null","tryCatchPattern":"try {\n    byte[] data = Kernel32Util.getResource(h, type, name);\n} catch (IllegalStateException e) {\n    // LockResource returned null despite successful load — native/JVM-level anomaly\n    throw new IllegalStateException(\"resource lock failed for \" + name, e);\n}","preventionTips":["Do not unload the module concurrently with resource reads","Use stock JNA Kernel32 mappings (custom mappings may break HRSRC/HANDLE types)","Retry resource extraction once before reporting failure","Escalate to the library maintainers if reproducible — LoadResource had succeeded"],"tags":["win32","jni","native","invariant-violation"],"backgroundTag":"internal-invariant-violation","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"}