{"record":{"id":"193803b1a9efd20d","repo":"jwtk/jjwt","slug":"unable-to-read-field-instanceclassname-fieldn","errorCode":null,"errorMessage":"Unable to read field ${instanceClassName}#${fieldName}: ${causeMessage}","messagePattern":"Unable to read field (.+?)#(.+?): (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/io/jsonwebtoken/lang/Classes.java","lineNumber":352,"sourceCode":"     * Returns the {@code instance}'s named (declared) field value.\n     *\n     * @param instance  the instance with the internal field\n     * @param fieldName the name of the field to inspect\n     * @param fieldType the type of field to inspect\n     * @param <T>       field instance value type\n     * @return the field value\n     */\n    public static <T> T getFieldValue(Object instance, String fieldName, Class<T> fieldType) {\n        if (instance == null) return null;\n        try {\n            Field field = instance.getClass().getDeclaredField(fieldName);\n            field.setAccessible(true);\n            Object o = field.get(instance);\n            return fieldType.cast(o);\n        } catch (Throwable t) {\n            String msg = \"Unable to read field \" + instance.getClass().getName() +\n                    \"#\" + fieldName + \": \" + t.getMessage();\n            throw new IllegalStateException(msg, t);\n        }\n    }\n\n    /**\n     * @since 1.0\n     */\n    private interface ClassLoaderAccessor {\n        Class<?> loadClass(String fqcn);\n\n        URL getResource(String name);\n\n        InputStream getResourceStream(String name);\n    }\n\n    /**\n     * @since 1.0\n     */\n    private static abstract class ExceptionIgnoringAccessor implements ClassLoaderAccessor {","sourceCodeStart":334,"sourceCodeEnd":370,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/api/src/main/java/io/jsonwebtoken/lang/Classes.java#L334-L370","documentation":"IllegalStateException thrown by io.jsonwebtoken.lang.Classes.getFieldValue when reflectively reading a declared field fails — field not found, setAccessible rejected, wrong fieldType cast, or instance/class mismatch. The message embeds the underlying cause message.","triggerScenarios":"getFieldValue(instance, fieldName, fieldType) where fieldName does not exist on instance's class, a SecurityManager/module system blocks setAccessible, or field.get returns an object not castable to fieldType.","commonSituations":"Poking at library internals whose field names changed between jjwt versions; JDK 9+ strong encapsulation denying access to private fields of non-exported packages; wrong expected type parameter causing ClassCastException.","solutions":["Verify the field name and type against the exact jar version on the classpath","Use the library's public API instead of reading internal fields","For JDK 9+, add --add-opens / module opens if access is intentional and unavoidable","Match fieldType to the field's declared type to avoid the cast failure"],"exampleFix":"// before\nString alg = Classes.getFieldValue(header, \"algx\", String.class); // wrong field name\n// after\nString alg = Classes.getFieldValue(header, \"alg\", String.class);","handlingStrategy":"try-catch","validationCode":"try {\n    java.lang.reflect.Field f = instance.getClass().getDeclaredField(fieldName);\n    if (!fieldType.isAssignableFrom(f.getType())) {\n        throw new IllegalArgumentException(\"Field \" + fieldName + \" is not \" + fieldType);\n    }\n} catch (NoSuchFieldException e) {\n    throw new IllegalArgumentException(\"No field \" + fieldName + \" on \" + instance.getClass());\n}","typeGuard":null,"tryCatchPattern":"try {\n    return Classes.getFieldValue(instance, fieldName, fieldType);\n} catch (IllegalStateException e) {\n    LOG.warn(\"Reflective field read failed for {}.#{}, cause: {}\", instance.getClass(), fieldName, e.getCause());\n    return defaultValue;\n}","preventionTips":["Avoid reading library internals; use public APIs and accessors","Pin to a specific jjwt version since internal field names can change","On JDK 9+, add explicit --add-opens if reflective access is unavoidable"],"tags":["reflection","field-access","encapsulation"],"backgroundTag":"permission-denied","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}