java-native-access/jna · error · Win32Exception
Win32Exception from native GetLastError after LoadLibraryEx
Error message
Win32Exception from native GetLastError after LoadLibraryEx failed
What it means
getResource(path, type, name) extracts an embedded resource from an executable/DLL by loading it with LoadLibraryEx using LOAD_LIBRARY_AS_DATAFILE. If LoadLibraryEx returns null, the wrapper throws Win32Exception with the native GetLastError code — typically ERROR_MOD_NOT_FOUND (file missing or its dependencies unreadable) or ERROR_BAD_EXE_FORMAT (not a valid PE file / 32-vs-64-bit mismatch).
Source
Thrown at contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java:985
/**
* Gets the specified resource out of the specified executable file
*
* @param path
* The path to the executable file
* @param type
* The type of the resource (either a type name or type ID is
* allowed)
* @param name
* The name or ID of the resource
* @return The resource bytes, or null if no such resource exists.
* @throws IllegalStateException if the call to LockResource fails
*/
public static byte[] getResource(String path, String type, String name) {
HMODULE target = Kernel32.INSTANCE.LoadLibraryEx(path, null, Kernel32.LOAD_LIBRARY_AS_DATAFILE);
if (target == null) {
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
Win32Exception err = null;
Pointer start = null;
int length = 0;
byte[] results = null;
try {
Pointer t = null;
try {
t = new Pointer(Long.parseLong(type));
} catch (NumberFormatException e) {
t = new Memory(Native.WCHAR_SIZE * (type.length() + 1));
t.setWideString(0, type);
}
Pointer n = null;
try {
n = new Pointer(Long.parseLong(name));View on GitHub (pinned to d036ad9781)
Solutions
- Verify the file exists and is a native PE (check MZ header) before calling: new File(path).isFile().
- Resolve the path to an absolute path to avoid dependence on the process working directory.
- Inspect Win32Exception.getErrorCode(): 126 (ERROR_MOD_NOT_FOUND) = missing file, 193 (ERROR_BAD_EXE_FORMAT) = wrong architecture/format.
- Catch Win32Exception and provide a fallback resource lookup or a clear user-facing message.
Example fix
// before
byte[] icon = Kernel32Util.getResource("notepad.exe", "RT_GROUP_ICON", "APP");
// after
Path exe = Paths.get("C:\\Windows\\notepad.exe").toAbsolutePath();
if (!Files.isRegularFile(exe)) {
throw new FileNotFoundException(exe.toString());
}
byte[] icon;
try {
icon = Kernel32Util.getResource(exe.toString(), "RT_GROUP_ICON", "APP");
} catch (Win32Exception e) {
throw new IOException("Cannot load resources from " + exe + " (code " + e.getErrorCode() + ")", e);
} Defensive patterns
Strategy: validation
Validate before calling
Path p = Paths.get(path).toAbsolutePath();
if (!Files.isRegularFile(p)) {
throw new FileNotFoundException(p.toString());
}
try (FileChannel ch = FileChannel.open(p, StandardOpenOption.READ)) {
byte[] hdr = new byte[2];
ch.read(ByteBuffer.wrap(hdr));
if (hdr[0] != 'M' || hdr[1] != 'Z') {
throw new IOException("Not a PE file: " + p);
}
} Try / catch
try {
return Kernel32Util.getResource(path, type, name);
} catch (Win32Exception e) {
throw new IOException("LoadLibraryEx failed for " + path + " (code " + e.getErrorCode() + ")", e);
} Prevention
- Resolve resource DLL paths to absolute files and verify existence first.
- Confirm the target is a native PE (MZ header); .NET managed-only assemblies can still load but expect mixed results.
- Match bitness expectations — ERROR_BAD_EXE_FORMAT (193) means wrong architecture.
- Watch for antivirus quarantine/locking of the target file.
When it happens
Trigger: Calling Kernel32Util.getResource(path, type, name) when LoadLibraryEx(path, null, LOAD_LIBRARY_AS_DATAFILE) returns null — the file path does not exist, the file is not a valid PE image, the path is a resource DLL for the wrong architecture, or the file cannot be opened due to permissions/locking.
Common situations: Typo'd or relative DLL path resolved against the wrong working directory; attempting to read resources from a .NET assembly or script that is not a native PE; antivirus quarantining/locking the file; extracting icons/strings from an executable that was since updated or removed.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- LookupAccountNameW was expected to fail with ERROR_INSUFFICI
- Expected GetTokenInformation to fail with ERROR_INSUFFICIENT
- Failed to find privilege "{privilege}" - {GetLastError}
- Win32Exception from native GetLastError after GetPrivateProf
- Win32Exception from native GetLastError after GetPrivateProf
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/cb2ebbdcf3038d32.
Report an issue: GitHub.