{"id":"6581e11e09982ad1","repo":"spring-projects/spring-framework","slug":"field-is-not-accessible","errorCode":null,"errorMessage":"Field is not accessible","messagePattern":"Field is not accessible","errorType":"exception","errorClass":"InvalidPropertyException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java","lineNumber":147,"sourceCode":"\t\t@Override\n\t\tpublic TypeDescriptor getCollectionType(int nestingLevel) {\n\t\t\treturn new TypeDescriptor(this.resolvableType.getNested(nestingLevel).asCollection().getGeneric(),\n\t\t\t\t\tnull, this.field.getAnnotations());\n\t\t}\n\n\t\t@Override\n\t\tpublic @Nullable TypeDescriptor nested(int level) {\n\t\t\treturn TypeDescriptor.nested(this.field, level);\n\t\t}\n\n\t\t@Override\n\t\tpublic @Nullable Object getValue() throws Exception {\n\t\t\ttry {\n\t\t\t\tReflectionUtils.makeAccessible(this.field);\n\t\t\t\treturn this.field.get(getWrappedInstance());\n\t\t\t}\n\t\t\tcatch (IllegalAccessException | InaccessibleObjectException ex) {\n\t\t\t\tthrow new InvalidPropertyException(getWrappedClass(),\n\t\t\t\t\t\tthis.field.getName(), \"Field is not accessible\", ex);\n\t\t\t}\n\t\t}\n\n\t\t@Override\n\t\tpublic void setValue(@Nullable Object value) throws Exception {\n\t\t\ttry {\n\t\t\t\tReflectionUtils.makeAccessible(this.field);\n\t\t\t\tthis.field.set(getWrappedInstance(), value);\n\t\t\t}\n\t\t\tcatch (IllegalAccessException | InaccessibleObjectException ex) {\n\t\t\t\tthrow new InvalidPropertyException(getWrappedClass(), this.field.getName(),\n\t\t\t\t\t\t\"Field is not accessible\", ex);\n\t\t\t}\n\t\t}\n\t}\n\n}","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java#L129-L165","documentation":"InvalidPropertyException thrown by DirectFieldAccessor.DirectFieldAccessorHandler.getValue() when java.lang.reflect.Field.get fails with IllegalAccessException or InaccessibleObjectException even after ReflectionUtils.makeAccessible. This is field-based (not accessor-based) access being blocked by the JVM, typically a module/permission boundary.","triggerScenarios":"Using DirectFieldAccessor to read a field on an instance of a class in a non-opened module under JPMS, or running under a SecurityManager that vetoes reflection; field belongs to a JDK class or a third-party module that does not 'open' its package to Spring.","commonSituations":"Injecting into JDK classes (java.lang, java.util) via field access; Spring test support reflecting into JDK types under Java 16+; SpringBoot on Java 17+ without the recommended --add-opens flags; third-party lib compiled as a JPMS module that doesn't open its packages.","solutions":["Add '--add-opens <module>/<package>=ALL-UNNAMED' (or the specific Spring module) to the JVM args.","Avoid field access into JDK/JVM internal classes; switch to accessor-based BeanWrapper where possible.","If on the classpath as a JPMS module, add 'opens' directives to module-info for the packages Spring must touch.","Run on Java 8-15 if you cannot add opens and field access is mandatory (not recommended long-term)."],"exampleFix":"# before\njava -jar app.jar  # InaccessibleObjectException on field read\n\n# after\njava --add-opens java.base/java.lang=ALL-UNNAMED \\\n     --add-opens my.module/com.example.beans=ALL-UNNAMED \\\n     -jar app.jar","handlingStrategy":"validation","validationCode":"// Pre-flight field read accessibility under the current JVM\nField f = target.getClass().getDeclaredField(fieldName);\ntry {\n    ReflectionUtils.makeAccessible(f);\n    f.setAccessible(true);\n    // try a no-op get to confirm\n    f.get(target);\n} catch (IllegalAccessException | InaccessibleObjectException e) {\n    throw new IllegalStateException(\"Field \" + fieldName + \" not accessible; add --add-opens\", e);\n}","typeGuard":"static boolean isFieldReadable(Class<?> clazz, String fieldName) {\n    try {\n        Field f = clazz.getDeclaredField(fieldName);\n        f.setAccessible(true);\n        f.get(null); // works for static; for instance use a probe instance\n        return true;\n    } catch (Exception e) { return false; }\n}","tryCatchPattern":"try {\n    return accessor.getPropertyValue(name);\n} catch (InvalidPropertyException ex) {\n    if (\"Field is not accessible\".equals(ex.getMessage())) {\n        log.error(\"Add --add-opens {}/{}=ALL-UNNAMED to JVM args\",\n            fieldDeclaringModule(targetClass), fieldDeclaringPackage(targetClass));\n    }\n    throw ex;\n}","preventionTips":["Add required --add-opens flags in your build/runtime scripts (Spring Boot's documented list).","Prefer constructor/setter injection over field injection to sidestep this entirely.","In tests, use spring-boot-starter-test which surfaces recommended opens.","Audit module-info of your own modules to 'opens' bean packages."],"tags":["field-access","direct-field-accessor","jpms","reflection","spring-beans"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}