{"record":{"id":"ae24e90624729be9","repo":"java-native-access/jna","slug":"can-t-determine-size-of-nested-structure","errorCode":null,"errorMessage":"Can't determine size of nested structure","messagePattern":"Can't determine size of nested structure","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Structure.java","lineNumber":1507,"sourceCode":"                }\n            }\n            catch (Exception e) {\n                throw new Error(\"Exception reading field '\" + f.getName() + \"' in \" + getClass(), e);\n            }\n        }\n    }\n\n    private Object initializeField(Field field, Class<?> type) {\n        Object value = null;\n        if (Structure.class.isAssignableFrom(type)\n            && !(ByReference.class.isAssignableFrom(type))) {\n            try {\n                value = newInstance((Class<? extends Structure>) type, PLACEHOLDER_MEMORY);\n                setFieldValue(field, value);\n            }\n            catch(IllegalArgumentException e) {\n                String msg = \"Can't determine size of nested structure\";\n                throw new IllegalArgumentException(msg, e);\n            }\n        }\n        else if (NativeMapped.class.isAssignableFrom(type)) {\n            NativeMappedConverter tc = NativeMappedConverter.getInstance(type);\n            value = tc.defaultValue();\n            setFieldValue(field, value);\n        }\n        return value;\n    }\n\n    private int addPadding(int calculatedSize) {\n        return addPadding(calculatedSize, structAlignment);\n    }\n\n    private int addPadding(int calculatedSize, int alignment) {\n        // Structure size must be an integral multiple of its alignment,\n        // add padding if necessary.\n        if (actualAlignType != ALIGN_NONE) {","sourceCodeStart":1489,"sourceCodeEnd":1525,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Structure.java#L1489-L1525","documentation":"JNA's Structure.initializeField() creates a placeholder instance of a nested (by-value) Structure field to determine its native size. When the nested structure's own constructor throws IllegalArgumentException (e.g. because its fields cannot be sized or instantiated), initializeField wraps it as \"Can't determine size of nested structure\". It indicates a field-layout problem in an embedded structure, not in the outer one.","triggerScenarios":"Declaring a Structure with a non-ByReference nested Structure field whose class cannot be instantiated or sized during calculateSize(): e.g. the nested structure throws in its field initialization, has a non-public default/Pointer constructor, or contains fields with no computable native size.","commonSituations":"Embedding an abstract or inner (non-static) Structure class as a by-value field; nested struct with a field of an unsupported type; nested Structure subclass whose constructor performs validation and throws IllegalArgumentException; refactor changing a nested class to non-public while keeping it a by-value member.","solutions":["Fix the root IllegalArgumentException in the cause chain - it names the nested Structure class that failed to instantiate or size.","Make the nested Structure class and its no-arg and (Pointer) constructors public and static (non-static inner classes cannot be instantiated reflectively).","Ensure every field in the nested Structure has a supported JNA type with a determinable native size.","If the member is really a pointer to a struct, change the field type to extend Structure.ByReference so JNA only needs pointer size."],"exampleFix":"// before\nclass Outer extends Structure {\n    private Inner inner; // non-public, non-static nested struct\n}\n// after\npublic static class Inner extends Structure { public int x; protected void getFieldOrder() {...} }\nclass Outer extends Structure {\n    public Inner inner;\n}","handlingStrategy":"validation","validationCode":"static <T extends Structure> void checkEmbeddable(Class<T> nested) {\n    if (java.lang.reflect.Modifier.isAbstract(nested.getModifiers()))\n        throw new IllegalStateException(nested + \" must be concrete to embed by value\");\n    if (nested.isMemberClass() && !java.lang.reflect.Modifier.isStatic(nested.getModifiers()))\n        throw new IllegalStateException(nested + \" must be a static class\");\n    try { nested.getConstructor(); nested.getConstructor(Pointer.class); }\n    catch (NoSuchMethodException e) { throw new IllegalStateException(nested + \" needs public no-arg and (Pointer) constructors\"); }\n}","typeGuard":"static boolean isEmbeddableByValue(Class<?> t) {\n    return Structure.class.isAssignableFrom(t)\n        && !Structure.ByReference.class.isAssignableFrom(t)\n        && !java.lang.reflect.Modifier.isAbstract(t.getModifiers())\n        && (t.getEnclosingClass() == null || java.lang.reflect.Modifier.isStatic(t.getModifiers()));\n}","tryCatchPattern":"try {\n    MyOuter outer = new MyOuter();\n    outer.size();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Can't determine size of nested structure\")) {\n        // inspect e.getCause() for the failing nested Structure class\n        throw new IllegalStateException(\"Fix nested struct: \" + e.getCause(), e);\n    }\n    throw e;\n}","preventionTips":["Always declare nested by-value Structure fields as public static classes with public no-arg and (Pointer) constructors","Use Structure.ByReference for pointer-to-struct members so JNA never needs the nested size","Add a unit test that calls size() on every Structure in the codebase to force layout calculation early","Check e.getCause() when wrapping occurs - JNA preserves the underlying IllegalArgumentException"],"tags":["jna","structure","nested-structure","reflection","native-layout"],"backgroundTag":"type-mismatch","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}