{"record":{"id":"f686e7d31781b288","repo":"java-native-access/jna","slug":"ffi-types-not-initialized","errorCode":null,"errorMessage":"FFI types not initialized","messagePattern":"FFI types not initialized","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/com/sun/jna/Structure.java","lineNumber":2076,"sourceCode":"                || typePointer.equals(FFITypes.ffi_type_sint16)\n                || typePointer.equals(FFITypes.ffi_type_uint32)\n                || typePointer.equals(FFITypes.ffi_type_sint32)\n                || typePointer.equals(FFITypes.ffi_type_uint64)\n                || typePointer.equals(FFITypes.ffi_type_sint64)\n                || typePointer.equals(FFITypes.ffi_type_pointer);\n        }\n\n        private static boolean isFloatType(FFIType type) {\n            Pointer typePointer = type.getPointer();\n            return typePointer.equals(FFITypes.ffi_type_float)\n                || typePointer.equals(FFITypes.ffi_type_double);\n        }\n\n        static {\n            if (Native.POINTER_SIZE == 0)\n                throw new Error(\"Native library not initialized\");\n            if (FFITypes.ffi_type_void == null)\n                throw new Error(\"FFI types not initialized\");\n            ffiTypeInfo.put(FFITypes.ffi_type_void, Structure.newInstance(FFIType.class, FFITypes.ffi_type_void));\n            ffiTypeInfo.put(FFITypes.ffi_type_float, Structure.newInstance(FFIType.class, FFITypes.ffi_type_float));\n            ffiTypeInfo.put(FFITypes.ffi_type_double, Structure.newInstance(FFIType.class, FFITypes.ffi_type_double));\n            ffiTypeInfo.put(FFITypes.ffi_type_longdouble, Structure.newInstance(FFIType.class, FFITypes.ffi_type_longdouble));\n            ffiTypeInfo.put(FFITypes.ffi_type_uint8, Structure.newInstance(FFIType.class, FFITypes.ffi_type_uint8));\n            ffiTypeInfo.put(FFITypes.ffi_type_sint8, Structure.newInstance(FFIType.class, FFITypes.ffi_type_sint8));\n            ffiTypeInfo.put(FFITypes.ffi_type_uint16, Structure.newInstance(FFIType.class, FFITypes.ffi_type_uint16));\n            ffiTypeInfo.put(FFITypes.ffi_type_sint16, Structure.newInstance(FFIType.class, FFITypes.ffi_type_sint16));\n            ffiTypeInfo.put(FFITypes.ffi_type_uint32, Structure.newInstance(FFIType.class, FFITypes.ffi_type_uint32));\n            ffiTypeInfo.put(FFITypes.ffi_type_sint32, Structure.newInstance(FFIType.class, FFITypes.ffi_type_sint32));\n            ffiTypeInfo.put(FFITypes.ffi_type_uint64, Structure.newInstance(FFIType.class, FFITypes.ffi_type_uint64));\n            ffiTypeInfo.put(FFITypes.ffi_type_sint64, Structure.newInstance(FFIType.class, FFITypes.ffi_type_sint64));\n            ffiTypeInfo.put(FFITypes.ffi_type_pointer, Structure.newInstance(FFIType.class, FFITypes.ffi_type_pointer));\n            for(FFIType f: ffiTypeInfo.values()) {\n                f.read();\n            }\n            storeTypeInfo(void.class, ffiTypeInfo.get(FFITypes.ffi_type_void));\n            storeTypeInfo(Void.class, ffiTypeInfo.get(FFITypes.ffi_type_void));","sourceCodeStart":2058,"sourceCodeEnd":2094,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Structure.java#L2058-L2094","documentation":"Structure's static initializer checks that FFITypes.ffi_type_void (and the other FFI type descriptors) were populated by native code. If the native library was loaded but did not initialize the FFI type table, Structure cannot map Java types to libffi descriptors, so it throws this Error from the static block (surfacing as ExceptionInInitializerError).","triggerScenarios":"First use of Structure when FFITypes.ffi_type_void is null — i.e. a version/ABI mismatch between the Java jna classes and the loaded jnidispatch native library, or native init partially completed without registering FFI types.","commonSituations":"Mixing a newer jna.jar with an older jnidispatch binary (or vice versa), manually loading a system libjnidispatch that exports a different ABI, custom builds of JNA where FFI type initialization was skipped, or corrupted native extraction in the temp directory.","solutions":["Remove stale extracted natives from the JNA temp dir (or set -Djna.tmpdir to a fresh location) so the correct jnidispatch is re-extracted","Ensure the jna.jar version and native jnidispatch come from the same build; upgrade both to the latest JNA release together","Do not override native loading with -Djna.nosys or a system-installed libjnidispatch unless it matches the jar's expected ABI","Rebuild jnidispatch from the matching JNA source if using a custom native build","Catch ExceptionInInitializerError on first Structure use and log the JNA version (Native.VERSION) plus native library path to spot the mismatch"],"exampleFix":"// before\nclasspath: jna-5.13.0.jar + manually copied libjnidispatch.so from 5.2.0\n// after\nclasspath: jna-5.13.0.jar only (natives bundled in same artifact, same build)","handlingStrategy":"try-catch","validationCode":"boolean ffiReady() {\n    try { return com.sun.jna.Native.POINTER_SIZE != 0; }\n    catch (Throwable t) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n    new MyStructure();\n} catch (ExceptionInInitializerError e) {\n    // cause \"FFI types not initialized\" => jar/native version mismatch\n    throw new IllegalStateException(\"JNA jar/native ABI mismatch; check Native.VERSION=\" + com.sun.jna.Native.VERSION, e.getCause());\n}","preventionTips":["Never mix jna.jar versions with externally supplied jnidispatch binaries","Clear JNA's extracted-native temp dir after upgrades","Avoid -Djna.nosys unless the bundled natives are known-good","Pin JNA to a single version across all modules (dependency convergence check)"],"tags":["jna","ffi","static-initializer","abi-mismatch"],"backgroundTag":"module-init-failed","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"}