MyCATApache/Mycat-Server · error · ObjectAccessException
Could not set field @
Error message
Could not set field ${fieldName}@${objectClass} What it means
writeField sets a field value via reflection (field.set). When the JVM rejects the write with IllegalArgumentException (value/object type mismatch) or IllegalAccessException (field not accessible), it throws ObjectAccessException 'Could not set field <name>@<class>'. This guards the deserialization path from silently leaving fields unset.
Solutions
- Verify the value's runtime type matches the field's declared type before calling writeField
- Call field.setAccessible(true) or add JVM --add-opens for the package holding the class
- Check that object.getClass() actually declares/inherits the field; pass the correct definedIn class
- Read the cause exception (IllegalArgumentException vs IllegalAccessException) to pinpoint type vs access problem
Example fix
// before provider.writeField(obj, "port", "8080", null); // String into int field // after provider.writeField(obj, "port", 8080, null); // correct type
Defensive patterns
Strategy: validation
Validate before calling
Field f = obj.getClass().getDeclaredField(fieldName);
f.setAccessible(true);
if (value != null && !f.getType().isInstance(value)) {
throw new IllegalArgumentException(fieldName + " expects " + f.getType() + ", got " + value.getClass());
} Type guard
boolean writable = f.getType().isInstance(value) && declaringClass.isInstance(obj);
Try / catch
try {
provider.writeField(obj, name, value, definedIn);
} catch (ObjectAccessException e) {
log.error("cannot set {} on {}: {}", name, obj.getClass(), e.getCause());
} Prevention
- Match value runtime type to field declared type
- Make fields accessible via setAccessible before writes
- Pass the correct definedIn class for inherited fields
- Prefer setters over direct field writes
When it happens
Trigger: field.set(object, value) throws IllegalArgumentException because value's type is not assignable to the field type (or object is not an instance of the declaring class), or IllegalAccessException because the field is private/protected and not made accessible.
Common situations: Deserialized XML value type does not match the target field type (e.g. String into int); field became private in a newer class version; wrong object instance passed with a fieldName defined in a different class in the hierarchy.
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
- Array has wrong size:
- Cannot construct
- Cannot construct as it does not have a no-args constructor
- Cannot create by JDK serialization
- Constructor for threw an exception
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/56f7d54434803ecf.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/config/util/ReflectionProvider.java:110
validateFieldAccess(field);
try {
Object value = field.get(object);
visitor.visit(field.getName(), field.getType(), field.getDeclaringClass(), value);
} catch (IllegalArgumentException e) {
throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e);
} catch (IllegalAccessException e) {
throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e);
}
}
}
public void writeField(Object object, String fieldName, Object value, Class<?> definedIn) {
Field field = fieldDictionary.field(object.getClass(), fieldName, definedIn);
validateFieldAccess(field);
try {
field.set(object, value);
} catch (IllegalArgumentException e) {
throw new ObjectAccessException("Could not set field " + field.getName() + "@" + object.getClass(), e);
} catch (IllegalAccessException e) {
throw new ObjectAccessException("Could not set field " + field.getName() + "@" + object.getClass(), e);
}
}
public void invokeMethod(Object object, String methodName, Object value, Class<?> definedIn) {
try {
Method method = object.getClass().getMethod(methodName, new Class[] { value.getClass() });
method.invoke(object, new Object[] { value });
} catch (Exception e) {
throw new ObjectAccessException("Could not invoke " + object.getClass() + "." + methodName, e);
}
}
public Class<?> getFieldType(Object object, String fieldName, Class<?> definedIn) {
return fieldDictionary.field(object.getClass(), fieldName, definedIn).getType();
}
View on GitHub (pinned to 65f8d8beb7)