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

  1. Ensure the module handle stays valid (do not call FreeLibrary while reading resources)
  2. Catch Win32Exception and log errorCode to identify the native cause (e.g. ERROR_INVALID_HANDLE 6)
  3. Re-load the module with LoadLibraryEx(path, null, LOAD_LIBRARY_AS_DATAFILE) and retry
  4. 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

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


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/093b2416dffb6624. Report an issue: GitHub.