java-native-access/jna · critical · Error
FFI types not initialized
Error message
FFI types not initialized
What it means
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).
Source
Thrown at src/com/sun/jna/Structure.java:2076
|| typePointer.equals(FFITypes.ffi_type_sint16)
|| typePointer.equals(FFITypes.ffi_type_uint32)
|| typePointer.equals(FFITypes.ffi_type_sint32)
|| typePointer.equals(FFITypes.ffi_type_uint64)
|| typePointer.equals(FFITypes.ffi_type_sint64)
|| typePointer.equals(FFITypes.ffi_type_pointer);
}
private static boolean isFloatType(FFIType type) {
Pointer typePointer = type.getPointer();
return typePointer.equals(FFITypes.ffi_type_float)
|| typePointer.equals(FFITypes.ffi_type_double);
}
static {
if (Native.POINTER_SIZE == 0)
throw new Error("Native library not initialized");
if (FFITypes.ffi_type_void == null)
throw new Error("FFI types not initialized");
ffiTypeInfo.put(FFITypes.ffi_type_void, Structure.newInstance(FFIType.class, FFITypes.ffi_type_void));
ffiTypeInfo.put(FFITypes.ffi_type_float, Structure.newInstance(FFIType.class, FFITypes.ffi_type_float));
ffiTypeInfo.put(FFITypes.ffi_type_double, Structure.newInstance(FFIType.class, FFITypes.ffi_type_double));
ffiTypeInfo.put(FFITypes.ffi_type_longdouble, Structure.newInstance(FFIType.class, FFITypes.ffi_type_longdouble));
ffiTypeInfo.put(FFITypes.ffi_type_uint8, Structure.newInstance(FFIType.class, FFITypes.ffi_type_uint8));
ffiTypeInfo.put(FFITypes.ffi_type_sint8, Structure.newInstance(FFIType.class, FFITypes.ffi_type_sint8));
ffiTypeInfo.put(FFITypes.ffi_type_uint16, Structure.newInstance(FFIType.class, FFITypes.ffi_type_uint16));
ffiTypeInfo.put(FFITypes.ffi_type_sint16, Structure.newInstance(FFIType.class, FFITypes.ffi_type_sint16));
ffiTypeInfo.put(FFITypes.ffi_type_uint32, Structure.newInstance(FFIType.class, FFITypes.ffi_type_uint32));
ffiTypeInfo.put(FFITypes.ffi_type_sint32, Structure.newInstance(FFIType.class, FFITypes.ffi_type_sint32));
ffiTypeInfo.put(FFITypes.ffi_type_uint64, Structure.newInstance(FFIType.class, FFITypes.ffi_type_uint64));
ffiTypeInfo.put(FFITypes.ffi_type_sint64, Structure.newInstance(FFIType.class, FFITypes.ffi_type_sint64));
ffiTypeInfo.put(FFITypes.ffi_type_pointer, Structure.newInstance(FFIType.class, FFITypes.ffi_type_pointer));
for(FFIType f: ffiTypeInfo.values()) {
f.read();
}
storeTypeInfo(void.class, ffiTypeInfo.get(FFITypes.ffi_type_void));
storeTypeInfo(Void.class, ffiTypeInfo.get(FFITypes.ffi_type_void));View on GitHub (pinned to d036ad9781)
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
Example fix
// before classpath: jna-5.13.0.jar + manually copied libjnidispatch.so from 5.2.0 // after classpath: jna-5.13.0.jar only (natives bundled in same artifact, same build)
Defensive patterns
Strategy: try-catch
Validate before calling
boolean ffiReady() {
try { return com.sun.jna.Native.POINTER_SIZE != 0; }
catch (Throwable t) { return false; }
} Try / catch
try {
new MyStructure();
} catch (ExceptionInInitializerError e) {
// cause "FFI types not initialized" => jar/native version mismatch
throw new IllegalStateException("JNA jar/native ABI mismatch; check Native.VERSION=" + com.sun.jna.Native.VERSION, e.getCause());
} Prevention
- 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)
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Error looking up CallbackProxy.callback() method
- Error loading DLLCallback class
- This method must be called from the static initializer of a
- Native library not initialized
- No support for " + os
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/f686e7d31781b288.
Report an issue: GitHub.