{"record":{"id":"e25933d80170c5b6","repo":"java-native-access/jna","slug":"type-type-has-unknown-native-alignment","errorCode":null,"errorMessage":"Type \" + type + \" has unknown native alignment\"","messagePattern":"Type \" \\+ type \\+ \" has unknown native alignment\"","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Structure.java","lineNumber":1589,"sourceCode":"                 || WString.class == type\n                 || String.class == type) {\n            alignment = Native.POINTER_SIZE;\n        }\n        else if (Structure.class.isAssignableFrom(type)) {\n            if (ByReference.class.isAssignableFrom(type)) {\n                alignment = Native.POINTER_SIZE;\n            }\n            else {\n                if (value == null)\n                    value = newInstance((Class<? extends Structure>) type, PLACEHOLDER_MEMORY);\n                alignment = ((Structure)value).getStructAlignment();\n            }\n        }\n        else if (type.isArray()) {\n            alignment = getNativeAlignment(type.getComponentType(), null, isFirstElement);\n        }\n        else {\n            throw new IllegalArgumentException(\"Type \" + type + \" has unknown \"\n                                               + \"native alignment\");\n        }\n        if (actualAlignType == ALIGN_NONE) {\n            alignment = 1;\n        }\n        else if (actualAlignType == ALIGN_MSVC) {\n            alignment = Math.min(8, alignment);\n        }\n        else if (actualAlignType == ALIGN_GNUC) {\n            // NOTE this is published ABI for 32-bit gcc/linux/x86, osx/x86,\n            // and osx/ppc.  osx/ppc special-cases the first element\n            if (!isFirstElement || !(Platform.isMac() && Platform.isPPC())) {\n                alignment = Math.min(Native.MAX_ALIGNMENT, alignment);\n            }\n            if (!isFirstElement && Platform.isAIX() && (type == double.class || type == Double.class)) {\n                alignment = 4;\n            }\n        }","sourceCodeStart":1571,"sourceCodeEnd":1607,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Structure.java#L1571-L1607","documentation":"Structure.getNativeAlignment() computes the native byte alignment for a field type. If the type is not a primitive, Pointer/Buffer/Callback/String/WString, Structure, NativeMapped, or array, JNA has no rule for it and throws \"Type ... has unknown native alignment\". This means a field type in the Structure is not mappable to a native type.","triggerScenarios":"Declaring a Structure field whose Java type is not one of JNA's supported types (e.g. java.math.BigInteger, a POJO, java.util.Date, a generic Object) and is not covered by a NativeMapped or TypeMapper conversion, then triggering layout calculation (instantiation, getSize(), or a native call).","commonSituations":"Migrating a struct field from int to a wrapper/POJO type; forgetting a TypeMapper/@Structure.FieldOrder mapping for a custom class; passing a Collection or Optional as a struct field; auto-generated struct classes containing unsupported JDK types.","solutions":["Replace the field with a JNA-supported type (primitive, Pointer, String/WString, Buffer, Callback, array, or nested Structure).","If the custom type maps to a native value, implement NativeMapped (with NativeMappedConverter) on that class so getNativeAlignment can resolve its nativeType().","Register a TypeMapper (e.g. via Structure setTypeMapper or a library-level mapper) converting the unsupported class to a supported one.","If it should be an opaque handle, use com.sun.jna.PointerType or Pointer.ByReference instead of the arbitrary object type."],"exampleFix":"// before\npublic class Status { private int code; } // POJO field\npublic Status status;\n// after\npublic class Status extends IntegerType implements NativeMapped { public Status() { super(4, true); this.code = 0; } }\npublic Status status;","handlingStrategy":"type-guard","validationCode":"static void validateFieldTypes(Class<? extends Structure> cls) {\n    for (Field f : cls.getDeclaredFields()) {\n        Class<?> t = f.getType();\n        boolean ok = t.isPrimitive() || Pointer.class.isAssignableFrom(t) || Structure.class.isAssignableFrom(t)\n            || t.isArray() || String.class == t || WString.class == t\n            || Buffer.class.isAssignableFrom(t) || Callback.class.isAssignableFrom(t)\n            || NativeMapped.class.isAssignableFrom(t);\n        if (!ok) throw new IllegalStateException(\"Field \" + f + \" has unsupported native type \" + t);\n    }\n}","typeGuard":"static boolean hasKnownNativeAlignment(Class<?> t) {\n    return t.isPrimitive() || Pointer.class.isAssignableFrom(t)\n        || Structure.class.isAssignableFrom(t) || t.isArray()\n        || String.class == t || WString.class == t\n        || Buffer.class.isAssignableFrom(t) || Callback.class.isAssignableFrom(t)\n        || NativeMapped.class.isAssignableFrom(t);\n}","tryCatchPattern":"try {\n    MyStruct s = new MyStruct();\n    int size = s.size();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"unknown native alignment\")) {\n        throw new IllegalStateException(\"Replace unsupported field type named in: \" + e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Restrict Structure fields to JNA-mappable types; model handles with Pointer/PointerType and integers with IntegerType","Implement NativeMapped for custom value classes so they resolve to a native type","Run a smoke test that allocates every Structure at startup to surface layout errors before native calls","Remember error message includes the offending type name - check it first when debugging"],"tags":["jna","structure","alignment","unsupported-type","native-layout"],"backgroundTag":"unsupported-operation","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"}