java-native-access/jna · warning · RuntimeException

Failed to call addSuppressedMethod

Error message

Failed to call addSuppressedMethod

What it means

Win32Exception.addSuppressedReflected() attaches a suppressed exception via a reflectively-obtained Throwable.addSuppressed method (a NOOP on JDKs without it). If the reflective invocation itself fails (illegal access, bad arguments, or the target threw), the library wraps the failure in this RuntimeException. It signals reflection plumbing broke, usually not a user data problem.

Source

Thrown at contrib/platform/src/com/sun/jna/platform/win32/Win32Exception.java:96

    static {
        try {
            addSuppressedMethod = Throwable.class.getMethod("addSuppressed", Throwable.class);
        } catch (NoSuchMethodException ex) {
            // This is the case for JDK < 7
        } catch (SecurityException ex) {
            Logger.getLogger(Win32Exception.class.getName()).log(Level.SEVERE, "Failed to initialize 'addSuppressed' method", ex);
        }
    }

    void addSuppressedReflected(Throwable exception) {
        if(addSuppressedMethod == null) {
            // Make this a NOOP on an unsupported JDK
            return;
        }
        try {
            addSuppressedMethod.invoke(this, exception);
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
            throw new RuntimeException("Failed to call addSuppressedMethod", ex);
        }
    }
}

View on GitHub (pinned to d036ad9781)

Solutions

  1. Upgrade to a supported standard JDK so addSuppressed resolves and invokes normally.
  2. Remove SecurityManager / reflective-access restrictions for the library's packages (add-opens if needed).
  3. Catch the RuntimeException and log it — the original Win32Exception is still valid and usable.
  4. Ensure the library version matches the target JDK line (re-check the addSuppressed NOOP guard).

Example fix

// before
ex.addSuppressedReflected(suppressed); // may throw
// after
try {
    ex.addSuppressedReflected(suppressed);
} catch (RuntimeException reflectionFailure) {
    logger.warning("could not attach suppressed: " + reflectionFailure);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// check JVM supports reflective addSuppressed before use
Method m = Throwable.class.getMethod("addSuppressed", Throwable.class);
m.setAccessible(true); // throws if access is denied -> environment will fail

Try / catch

try {
    ex.addSuppressedReflected(suppressed);
} catch (RuntimeException e) {
    logger.warning("addSuppressed failed; original exception still usable", e);
}

Prevention

When it happens

Trigger: Calling addSuppressedReflected (directly or via paths like getCurrentUserGroups, accessCheck, cryptProtectData/cryptUnprotectData, getScreenshot, closeHandleRefs) on a JVM where the cached addSuppressed Method handle cannot be invoked — e.g. a security manager denying reflective access, or a JDK where the method signature lookup mismatches.

Common situations: Running under a strict SecurityManager or module restrictions (JPMS strong encapsulation); exotic/very old JVMs the reflection check misclassified; bytecode/repackage environments (certain shaded/Android-like runtimes).

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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