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

  1. Verify the value's runtime type matches the field's declared type before calling writeField
  2. Call field.setAccessible(true) or add JVM --add-opens for the package holding the class
  3. Check that object.getClass() actually declares/inherits the field; pass the correct definedIn class
  4. 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

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


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)