java-native-access/jna · error · Win32Exception
Win32Exception from native GetLastError after LoadResource f
Error message
Win32Exception from native GetLastError after LoadResource failed
What it means
Kernel32Util throws this Win32Exception when Kernel32.INSTANCE.LoadResource returns null after a successful FindResource. The native GetLastError code is wrapped, surfacing why the resource handle could not be loaded (e.g. the module handle became invalid or the resource data is corrupt).
Source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java:1017
}
Pointer n = null;
try {
n = new Pointer(Long.parseLong(name));
} catch (NumberFormatException e) {
n = new Memory(Native.WCHAR_SIZE * (name.length() + 1));
n.setWideString(0, name);
}
HRSRC hrsrc = Kernel32.INSTANCE.FindResource(target, n, t);
if (hrsrc == null) {
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 {View on GitHub (pinned to d036ad9781)
Solutions
- Ensure the module handle stays valid (do not call FreeLibrary while reading resources)
- Catch Win32Exception and log errorCode to identify the native cause (e.g. ERROR_INVALID_HANDLE 6)
- Re-load the module with LoadLibraryEx(path, null, LOAD_LIBRARY_AS_DATAFILE) and retry
- Verify the binary is not truncated/corrupt (checksum, file size)
Example fix
// before
HANDLE h = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE);
byte[] data = Kernel32Util.getResource(h, type, name);
Kernel32.INSTANCE.FreeLibrary(h); // freed while/after use
// after
HANDLE h = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE);
try {
byte[] data = Kernel32Util.getResource(h, type, name);
} finally {
Kernel32.INSTANCE.FreeLibrary(h);
} Defensive patterns
Strategy: try-catch
Validate before calling
HANDLE h = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE); if (h == null) throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); // keep h referenced until getResource completes
Type guard
boolean isValidHandle(HANDLE h) { return h != null && !Native.INVALID_HANDLE_VALUE.equals(h); } Try / catch
try {
byte[] data = Kernel32Util.getResource(h, type, name);
} catch (Win32Exception e) {
log.warn("LoadResource failed, native code=" + e.getErrorCode(), e);
throw e;
} Prevention
- Never FreeLibrary a module while resource extraction is in flight
- Load the module as a datafile in the same scope that reads the resource
- Verify the binary is not truncated (compare size/checksum)
- Keep a single HMODULE instance for Find/Load/Size/Lock calls
When it happens
Trigger: Calling Kernel32Util.getResource(...) where FindResource succeeded (returned a valid HRSRC) but LoadResource(target, hrsrc) fails, typically because the target module handle is invalid, the library was unloaded concurrently, or the resource data is damaged.
Common situations: Freeing/FreeLibrary the module from another thread while getResource runs; passing an HMODULE from a module that failed to fully load as a datafile; corrupt binaries (truncated downloads).
Related errors
- Win32Exception from native GetLastError after FindResource f
- Win32Exception from native GetLastError when SizeofResource
- LockResource returned null.
- 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/093b2416dffb6624.
Report an issue: GitHub.