java-native-access/jna · error · Win32Exception

Win32Exception from native GetLastError after SetPriorityCla

Error message

Win32Exception from native GetLastError after SetPriorityClass failed

What it means

setCurrentProcessPriority(DWORD) throws this Win32Exception when the argument passes isValidPriorityClass() but the native SetPriorityClass call returns FALSE. The exception carries the GetLastError() code, most commonly ERROR_ACCESS_DENIED, because raising priority (especially REALTIME) requires elevated privileges.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/Kernel32Util.java:1286

        final DWORD dwPriorityClass = Kernel32.INSTANCE.GetPriorityClass(Kernel32.INSTANCE.GetCurrentProcess());
        if (!isValidPriorityClass(dwPriorityClass)) {
            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
        }
        return dwPriorityClass;
    }

    /**
     * Sets the priority class for the current process.
     *
     * @param dwPriorityClass The priority class for the process.
     * @throws Win32Exception if an error occurs.
     */
    public static void setCurrentProcessPriority(final DWORD dwPriorityClass) {
        if (!isValidPriorityClass(dwPriorityClass)) {
            throw new IllegalArgumentException("The given priority value is invalid!");
        }
        if (!Kernel32.INSTANCE.SetPriorityClass(Kernel32.INSTANCE.GetCurrentProcess(), dwPriorityClass)) {
            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
        }
    }

    /**
     * Enables or disables "background" processing mode for the current process
     *
     * @param enable If true, enables "background" processing mode, otherwise disables it.
     * @throws Win32Exception if an error occurs.
     */
    public static void setCurrentProcessBackgroundMode(final boolean enable) {
        // Note: PROCESS_MODE_BACKGROUN_{BEGIN,END} only works with the "current" process handle!
        final DWORD dwPriorityClass = enable ? Kernel32.PROCESS_MODE_BACKGROUND_BEGIN : Kernel32.PROCESS_MODE_BACKGROUND_END;
        if (!Kernel32.INSTANCE.SetPriorityClass(Kernel32.INSTANCE.GetCurrentProcess(), dwPriorityClass)) {
            throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
        }
    }

    /**

View on GitHub (pinned to d036ad9781)

Solutions

  1. Run the process elevated (administrator) when setting HIGH or REALTIME priority classes.
  2. Prefer ABOVE_NORMAL_PRIORITY_CLASS instead of REALTIME/HIGH — it usually succeeds without elevation.
  3. Inspect Win32Exception.getErrorCode() (ERROR_ACCESS_DENIED = 5) and degrade gracefully.
  4. Wrap the call in try-catch and keep the current priority if the change fails.

Example fix

// before
Kernel32Util.setCurrentProcessPriority(Kernel32.REALTIME_PRIORITY_CLASS);
// after
try {
    Kernel32Util.setCurrentProcessPriority(Kernel32.HIGH_PRIORITY_CLASS);
} catch (Win32Exception e) {
    LOG.warn("Priority change denied (code " + e.getErrorCode() + "), running at normal priority");
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!Kernel32Util.isValidPriorityClass(dwPriorityClass)) {
    throw new IllegalArgumentException("invalid priority class");
}
// REALTIME typically requires elevation:
boolean elevated = Kernel32.REALTIME_PRIORITY_CLASS.equals(dwPriorityClass) && !isAdmin();
if (elevated) { /* request elevation or downgrade class */ }

Try / catch

try {
    Kernel32Util.setCurrentProcessPriority(cls);
} catch (Win32Exception e) {
    if (e.getErrorCode() == WinError.ERROR_ACCESS_DENIED) {
        log.warn("Priority change denied; continuing at current priority");
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling Kernel32Util.setCurrentProcessPriority() with a valid class like REALTIME_PRIORITY_CLASS or HIGH_PRIORITY_CLASS from a non-elevated process on Windows; SetPriorityClass fails and GetLastError() is non-zero.

Common situations: Applications trying to boost their own priority without administrator rights; UAC-restricted processes; job objects or group policies limiting priority changes; attempting REALTIME_PRIORITY_CLASS which normally requires SeIncreaseBasePriorityPrivilege.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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