{"id":"279ac4d36e96a53b","repo":"google/gson","slug":"unexpected-illegalaccessexception-occurred-gson","errorCode":null,"errorMessage":"Unexpected IllegalAccessException occurred (Gson \" + GsonBuildConfig.VERSION + \"). Certain ReflectionAccessFilter features require Java >= 9 to work correctly. If you are not using ReflectionAccessFilter, report this to the Gson maintainers.","messagePattern":"Unexpected IllegalAccessException occurred \\(Gson \" \\+ GsonBuildConfig\\.VERSION \\+ \"\\)\\. Certain ReflectionAccessFilter features require Java >= 9 to work correctly\\. If you are not using ReflectionAccessFilter, report this to the Gson maintainers\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/reflect/ReflectionHelper.java","lineNumber":201,"sourceCode":"    return RECORD_HELPER.isRecord(raw);\n  }\n\n  public static String[] getRecordComponentNames(Class<?> raw) {\n    return RECORD_HELPER.getRecordComponentNames(raw);\n  }\n\n  /** Looks up the record accessor method that corresponds to the given record field */\n  public static Method getAccessor(Class<?> raw, Field field) {\n    return RECORD_HELPER.getAccessor(raw, field);\n  }\n\n  public static <T> Constructor<T> getCanonicalRecordConstructor(Class<T> raw) {\n    return RECORD_HELPER.getCanonicalRecordConstructor(raw);\n  }\n\n  public static RuntimeException createExceptionForUnexpectedIllegalAccess(\n      IllegalAccessException exception) {\n    throw new RuntimeException(\n        \"Unexpected IllegalAccessException occurred (Gson \"\n            + GsonBuildConfig.VERSION\n            + \"). Certain ReflectionAccessFilter features require Java >= 9 to work correctly. If\"\n            + \" you are not using ReflectionAccessFilter, report this to the Gson maintainers.\",\n        exception);\n  }\n\n  private static RuntimeException createExceptionForRecordReflectionException(\n      ReflectiveOperationException exception) {\n    throw new RuntimeException(\n        \"Unexpected ReflectiveOperationException occurred\"\n            + \" (Gson \"\n            + GsonBuildConfig.VERSION\n            + \").\"\n            + \" To support Java records, reflection is utilized to read out information\"\n            + \" about records. All these invocations happens after it is established\"\n            + \" that records exist in the JVM. This exception is unexpected behavior.\",\n        exception);","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/internal/reflect/ReflectionHelper.java#L183-L219","documentation":"Gson treats an IllegalAccessException during normal reflective field access as an internal/should-not-happen condition. The helper createExceptionForUnexpectedIllegalAccess throws a RuntimeException noting that some ReflectionAccessFilter features need Java >= 9 and asking non-users of that filter to report the bug to Gson maintainers.","triggerScenarios":"An IllegalAccessException escapes Gson's normal makeAccessible flow on a JVM/configuration where it should not occur; most likely on Java 8 with a SecurityManager or an unusual module setup combined with ReflectionAccessFilter.","commonSituations":"Running Gson with a restrictive SecurityManager, mixing ReflectionAccessFilter with an older JVM, or hitting a genuine Gson bug in an unusual reflection scenario.","solutions":["Upgrade to Java 9+ if you use ReflectionAccessFilter features that require it.","Review your ReflectionAccessFilter configuration and ensure it matches your JVM capabilities.","If you do not use ReflectionAccessFilter, capture the full stack trace and file a bug with the Gson maintainers including GsonBuildConfig.VERSION from the message.","As a workaround, register a custom TypeAdapter for the affected type to bypass reflection."],"exampleFix":"// before: SecurityManager + Java 8 triggers unexpected IllegalAccessException\nGson gson = new GsonBuilder().addReflectionAccessFilter(...).create();\n\n// after: upgrade runtime and simplify filter usage\nGson gson = new GsonBuilder().create(); // drop filter or run on Java 9+","handlingStrategy":"try-catch","validationCode":"// Best-effort: detect restrictive runtime before Gson use.\nboolean isJava9OrLater() {\n  String v = System.getProperty(\"java.specification.version\");\n  return v != null && (v.matches(\"[9-9]\\\\d*\") || v.startsWith(\"1.8\") == false && Integer.parseInt(v.split(\"\\\\.\")[0]) >= 9);\n}","typeGuard":"static boolean reflectionFilterSafeOnThisJvm(boolean usesFilter) { return !usesFilter || isJava9OrLater(); }","tryCatchPattern":"try {\n  T obj = gson.fromJson(json, type);\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"Unexpected IllegalAccessException\")) {\n    // upgrade JVM or drop ReflectionAccessFilter; report to Gson if neither applies\n  } else throw e;\n}","preventionTips":["Pin a supported JDK in CI and production.","Avoid ReflectionAccessFilter on Java 8 unless documented as supported.","Capture GsonBuildConfig.VERSION when reporting."],"tags":["gson","reflection","runtime","java-version","bug-report"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}