java-native-access/jna · error · IllegalStateException
LockResource returned null.
Error message
LockResource returned null.
What it means
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.
Source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java:1029
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
// according to MSDN, on 32 bit Windows or newer, calling FreeResource() is not necessary - and in fact does nothing but return false.
HANDLE loaded = Kernel32.INSTANCE.LoadResource(target, hrsrc);
if (loaded == null) {
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
length = Kernel32.INSTANCE.SizeofResource(target, hrsrc);
if (length == 0) {
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
// MSDN: It is not necessary to unlock resources because the system automatically deletes them when the process that created them terminates.
// MSDN does not say that LockResource sets GetLastError
start = Kernel32.INSTANCE.LockResource(loaded);
if (start == null) {
throw new IllegalStateException("LockResource returned null.");
}
// have to capture it into a byte array before you free the library, otherwise bad things happen.
results = start.getByteArray(0, length);
} catch (Win32Exception we) {
err = we;
} finally {
// from what I can tell on MSDN, the only thing that needs cleanup on this is the HMODULE from LoadLibrary
if (target != null) {
if (!Kernel32.INSTANCE.FreeLibrary(target)) {
Win32Exception we = new Win32Exception(Kernel32.INSTANCE.GetLastError());
if (err != null) {
we.addSuppressedReflected(err);
}
throw we;
}
}
}
View on GitHub (pinned to d036ad9781)
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
Example fix
// before
byte[] data = Kernel32Util.getResource(h, type, name); // may throw IllegalStateException
// after
try {
byte[] data = Kernel32Util.getResource(h, type, name);
} catch (IllegalStateException e) {
throw new IllegalStateException("LockResource failed for resource " + name + " in " + h, e);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (target == null) throw new IllegalArgumentException("module handle required");
// ensure the module stays loaded: hold a reference and no FreeLibrary in this scope Type guard
null
Try / catch
try {
byte[] data = Kernel32Util.getResource(h, type, name);
} catch (IllegalStateException e) {
// LockResource returned null despite successful load — native/JVM-level anomaly
throw new IllegalStateException("resource lock failed for " + name, e);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Win32Exception from native GetLastError after FindResource f
- Win32Exception from native GetLastError after LoadResource f
- Win32Exception from native GetLastError when SizeofResource
- Win32Exception from native GetLastError after EnumResourceTy
- Win32Exception from native GetLastError after EnumResourceNa
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/8640ebd29df18b01.
Report an issue: GitHub.