{"record":{"id":"cdfad9216bdc7994","repo":"apache/flink","slug":"cannot-initialize-fields","errorCode":null,"errorMessage":"Cannot initialize fields.","messagePattern":"Cannot initialize fields\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/PojoSerializer.java","lineNumber":247,"sourceCode":"    private T instantiateRaw() {\n        try {\n            if (constructor == null) {\n                constructor = clazz.getDeclaredConstructor();\n                constructor.setAccessible(true);\n            }\n            return constructor.newInstance();\n        } catch (Exception e) {\n            throw new RuntimeException(\"Cannot instantiate class.\", e);\n        }\n    }\n\n    protected void initializeFields(T t) {\n        for (int i = 0; i < numFields; i++) {\n            if (fields[i] != null) {\n                try {\n                    fields[i].set(t, fieldSerializers[i].createInstance());\n                } catch (IllegalAccessException e) {\n                    throw new RuntimeException(\"Cannot initialize fields.\", e);\n                }\n            }\n        }\n    }\n\n    @Override\n    @SuppressWarnings({\"unchecked\", \"rawtypes\"})\n    public T copy(T from) {\n        if (from == null) {\n            return null;\n        }\n\n        Class<?> actualType = from.getClass();\n        if (isRecord()) {\n            try {\n                JavaRecordBuilderFactory<T>.JavaRecordBuilder builder = recordFactory.newBuilder();\n                for (int i = 0; i < numFields; i++) {\n                    if (fields[i] != null) {","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/PojoSerializer.java#L229-L265","documentation":"PojoSerializer.initializeFields() iterates every POJO field and sets it to a default instance produced by the field's own TypeSerializer.createInstance(). This RuntimeException is thrown when Field.set() raises an IllegalAccessException — meaning the JVM refused the reflective write even though the field was previously made accessible. It indicates an access-control or encapsulation barrier, not a missing constructor.","triggerScenarios":"After the POJO is successfully constructed via instantiateRaw(), initializeFields() calls fields[i].set(t, fieldSerializers[i].createInstance()). If the reflective set is denied, IllegalAccessException is caught and re-thrown with this message.","commonSituations":"The field is final and the JVM version enforces reflective-write restrictions on final fields; the POJO class is in a named module whose package is not 'open' to Flink, so setAccessible(true) silently fails or Field.set is rejected at call time; a security manager denies reflective field modification. This is rarer than errors 660/661 because fields are made accessible during serializer setup, but module-system tightening (Java 16+ strong encapsulation by default) makes it increasingly common.","solutions":["If using Java modules, add 'opens your.package to org.apache.flink.core' in module-info.java (or launch with --add-opens).","Remove the 'final' modifier from POJO fields that the serializer must write, or ensure the serializer does not need to initialize them (they are already non-null after construction).","Provide a TypeSerializerSnapshot / custom serializer so Flink does not rely on reflective field writes.","Verify that no SecurityManager or custom classloader is blocking reflective access.","As a last resort, annotate the type for Kryo serialization to bypass POjoSerializer entirely."],"exampleFix":"// before — final field in a sealed module; Field.set throws IllegalAccessException\npublic class Sensor {\n    public final String id;   // final + not open → reflective write denied\n    public Sensor() { this.id = \"\"; }\n}\n\n// after — remove final so the serializer can write the field at restore time\npublic class Sensor {\n    public String id;\n    public Sensor() { this.id = \"\"; }\n}","handlingStrategy":"validation","validationCode":"// Check that all non-static fields of the POJO are reflectively writable\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Modifier;\n\npublic static List<String> nonWritableFields(Class<?> clazz) {\n    List<String> bad = new ArrayList<>();\n    for (Field f : clazz.getDeclaredFields()) {\n        int mod = f.getModifiers();\n        if (Modifier.isStatic(mod)) continue;\n        try {\n            f.setAccessible(true);\n            // final fields may still reject set() on some JVMs\n            if (Modifier.isFinal(mod)) bad.add(f.getName() + \" (final)\");\n        } catch (SecurityException e) {\n            bad.add(f.getName() + \" (inaccessible)\");\n        }\n    }\n    return bad;\n}","typeGuard":null,"tryCatchPattern":"// initializeFields is called internally; guard at the type-registration level\nList<String> bad = nonWritableFields(MyPojo.class);\nif (!bad.isEmpty()) {\n    throw new IllegalStateException(\n        \"Fields not writable by PojoSerializer: \" + bad\n        + \" — remove 'final' or open the module\");\n}","preventionTips":["Avoid final instance fields in POJO types meant for PojoSerializer (or initialize them in the no-arg constructor so the serializer does not need to overwrite them).","Open the POJO package to Flink in module-info.java or via --add-opens.","Ensure no SecurityManager blocks reflective field modification.","Test PojoSerializer.createInstance() in CI for all domain types."],"tags":["pojo","serialization","reflection","field-access","java-modules"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}