google/gson · error · RuntimeException

Failed invoking canAccess

Error message

Failed invoking canAccess

What it means

Thrown when Gson's Java 9+ access checker cannot invoke AccessibleObject.canAccess(Object) via reflection. The wrapper 'Failed invoking canAccess' re-throws the underlying reflective invocation failure as a RuntimeException because Gson needs to know whether a field/method is accessible before using it, and an unexpected exception from canAccess itself is unrecoverable. The {c} placeholder is not interpolated here; the message is literal and the original exception is attached as the cause.

Source

Thrown at gson/src/main/java/com/google/gson/internal/ReflectionAccessFilterHelper.java:98

  private abstract static class AccessChecker {
    static final AccessChecker INSTANCE;

    static {
      AccessChecker accessChecker = null;
      // TODO: Ideally should use Multi-Release JAR for this version specific code
      if (JavaVersion.isJava9OrLater()) {
        try {
          Method canAccessMethod =
              AccessibleObject.class.getDeclaredMethod("canAccess", Object.class);
          accessChecker =
              new AccessChecker() {
                @Override
                public boolean canAccess(AccessibleObject accessibleObject, Object object) {
                  try {
                    return (Boolean) canAccessMethod.invoke(accessibleObject, object);
                  } catch (Exception e) {
                    throw new RuntimeException("Failed invoking canAccess", e);
                  }
                }
              };
        } catch (NoSuchMethodException ignored) {
          // OK: will assume everything is accessible
        }
      }

      if (accessChecker == null) {
        accessChecker =
            new AccessChecker() {
              @Override
              public boolean canAccess(AccessibleObject accessibleObject, Object object) {
                // Cannot determine whether object can be accessed, so assume it can be accessed
                return true;
              }
            };
      }

View on GitHub (pinned to 8b8628c656)

Solutions

  1. If using JPMS, add the required opens, e.g. run with --add-opens java.base/java.lang=ALL-UNNAMED (and opens for every package containing reflected classes), or declare them in module-info.
  2. Check the attached cause in the stack trace to identify the exact reflective failure (IllegalAccessException vs SecurityException vs IllegalArgumentException) and address that root cause.
  3. Disable the module/SecurityManager restriction, or run on a standard JDK where canAccess is reachable.
  4. If you cannot fix the environment, register a custom ReflectionAccessFilter returning BLOCK_INCLUSIVE_ALTERNATIVES / SERIALIZABLE or avoid reflective field access by registering explicit TypeAdapters for the affected types.

Example fix

// before: java ... -jar app.jar  (canAccess invoke fails under JPMS)

// after: grant reflective access at launch
java --add-opens java.base/java.util=ALL-UNNAMED \
     --add-opens com.example.data/com.example.data.model=ALL-UNNAMED \
     -jar app.jar
Defensive patterns

Strategy: try-catch

Validate before calling

// Before reflective heavy use, sanity-check module access at startup
try {
  java.lang.reflect.Method m = AccessibleObject.class.getDeclaredMethod("canAccess", Object.class);
  Field f = MyClass.class.getDeclaredField("x");
  m.invoke(f, new MyClass()); // will throw if access is blocked
} catch (Exception e) {
  throw new IllegalStateException("Gson reflective access blocked; add the required --add-opens", e);
}

Try / catch

try {
  return gson.fromJson(json, MyClass.class);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Failed invoking canAccess")) {
    throw new ConfigurationException("Gson cannot perform reflective access; launch JVM with --add-opens ...", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Occurs on Java 9+ only. The static initializer found AccessibleObject.canAccess and built the Java9 AccessChecker, but at runtime canAccessMethod.invoke(accessibleObject, object) threw (e.g. IllegalAccessException after the calling module lost access, a SecurityManager denying reflect access, or passing an object whose type mismatches the accessible object's declaring class for instance member checks).

Common situations: Running Gson under a strict JPMS setup without --add-opens to java.base; a SecurityManager that blocks reflective invocation; custom JVMs (GraalVM Native Image, some embedded runtimes) where canAccess behaves unexpectedly; concurrent classloading edge cases.

Related errors


AI-assisted analysis of google/gson@8b8628c656 (2026-08-04). Data as JSON: /data/errors/10f98fcc595bf3af.json. Report an issue: GitHub.