java-native-access/jna · error · java.lang.IllegalArgumentException
fieldName must be a public field of type resultClass.getName
Error message
fieldName must be a public field of type resultClass.getName() (e): mappingClass
What it means
JNA's lookupField helper reads optional public static fields (TYPE_MAPPER, STRUCTURE_ALIGNMENT, STRING_ENCODING) from a library mapping class. If the field exists but cannot be accessed or its value's type does not match the expected resultClass, it throws this IllegalArgumentException naming the field, expected type, and mapping class. A missing field is fine (returns null); a present-but-invalid field is not.
Source
Thrown at src/com/sun/jna/Native.java:883
libraryOptions = cacheOptions(mappingClass, libraryOptions, null);
// Store the original lookup class, if different from the mapping class
if (type != mappingClass) {
typeOptions.put(type, libraryOptions);
}
return libraryOptions;
}
private static Object lookupField(Class<?> mappingClass, String fieldName, Class<?> resultClass) {
try {
Field field = mappingClass.getField(fieldName);
field.setAccessible(true);
return field.get(null);
}
catch (NoSuchFieldException e) {
return null;
}
catch (Exception e) {
throw new IllegalArgumentException(fieldName + " must be a public field of type "
+ resultClass.getName() + " ("
+ e + "): " + mappingClass);
}
}
/** Return the preferred {@link TypeMapper} for the given native interface.
* See {@link com.sun.jna.Library#OPTION_TYPE_MAPPER}.
*/
public static TypeMapper getTypeMapper(Class<?> cls) {
Map<String, ?> options = getLibraryOptions(cls);
return (TypeMapper) options.get(Library.OPTION_TYPE_MAPPER);
}
/**
* @param cls The native interface type
* @return The preferred string encoding for the given native interface.
* If there is no setting, defaults to the {@link #getDefaultStringEncoding()}.
* @see com.sun.jna.Library#OPTION_STRING_ENCODINGView on GitHub (pinned to d036ad9781)
Solutions
- Correct the field's declared type to match the required type (TypeMapper, Integer, or String respectively) and make it public static
- Delete the field if the customization is unnecessary (absence is allowed)
- If using a TypeMapper.Provider, ensure it is assignable to the expected type and instantiates cleanly
- Check the embedded exception 'e' in the message for the root cause (IllegalAccessException vs ExceptionInInitializerError)
Example fix
// before public static int STRUCTURE_ALIGNMENT = Structure.ALIGN_DEFAULT; // after public static final Integer STRUCTURE_ALIGNMENT = Integer.valueOf(Structure.ALIGN_DEFAULT);
Defensive patterns
Strategy: validation
Validate before calling
static void checkOptionalField(Class<?> c, String name, Class<?> expected) throws Exception {
try {
Field f = c.getField(name);
Object v = f.get(null);
if (!expected.isInstance(v)) throw new IllegalStateException(name + " must be " + expected.getName());
} catch (NoSuchFieldException ok) { }
}
// usage: checkOptionalField(MyLib.class, "TYPE_MAPPER", TypeMapper.class); Type guard
boolean validOptional(Class<?> c, String name, Class<?> expected) {
try { Field f = c.getField(name); return expected.isInstance(f.get(null)); } catch (Exception e) { return false; }
} Try / catch
try { Native.load("mylib", MyLib.class); } catch (IllegalArgumentException e) { if (String.valueOf(e.getMessage()).startsWith("TYPE_MAPPER must be")) { throw new IllegalStateException("Check TYPE_MAPPER/STRUCTURE_ALIGNMENT/STRING_ENCODING declarations", e); } throw e; } Prevention
- Only add TYPE_MAPPER/STRUCTURE_ALIGNMENT/STRING_ENCODING fields with the exact documented types
- Use Integer (not int) for STRUCTURE_ALIGNMENT
- Ensure optional fields are public static and their initializers cannot throw
When it happens
Trigger: Declaring a public static field named TYPE_MAPPER (must be TypeMapper/FieldMapper or TypeMapper.Provider), STRUCTURE_ALIGNMENT (must be Integer), or STRING_ENCODING (must be String) with the wrong type, non-static, or a throwing initializer, then loading the library.
Common situations: Typing TYPE_MAPPER as a concrete class not implementing TypeMapper; making STRUCTURE_ALIGNMENT a raw int instead of Integer; STRING_ENCODING initialized with a non-String; initializer exceptions surfacing as the embedded cause.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Class type <paramTypes[i].getName()> not mapped to primitive
- OPTIONS must be a public field of type java.util.Map (e): ma
- OPTIONS must be a public field of type java.util.Map (<cause
- FileMonitor not implemented for " + os
- No trash location found (define fileutils.trash to be the pa
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/f6a4f0d5f6aa0c2d.
Report an issue: GitHub.