java-native-access/jna · error · Win32Exception
Win32Exception from native GetLastError after LoadResource…
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).
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…
- Win32Exception from native GetLastError when SizeofResource…
- LockResource returned null.
- Win32Exception from GetLastError after Module32NextW failed…
- Win32Exception from native GetLastError after…
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/093b2416dffb6624.
Report an issue: GitHub.
Appendix: 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)