MyCATApache/Mycat-Server · error · ObjectAccessException

Could not invoke .

Error message

Could not invoke ${objectClass}.${methodName}

What it means

invokeMethod reflects a setter method on the object and invokes it with a single value argument. Any failure inside the try block (NoSuchMethodException, wrong argument type, target invocation exception) is wrapped as ObjectAccessException 'Could not invoke <class>.<method>'. It signals the setter could not be located or the invocation itself failed.

Solutions

  1. Ensure a public method exists with signature exactly <name>(<value.getClass()>) — getMethod is exact-match
  2. Use the boxed type matching the setter parameter (e.g. Integer.class for int) or iterate getMethods() to find an assignable match
  3. Inspect e.getCause() (InvocationTargetException) for an exception thrown inside the setter itself
  4. Rename the configured property to the actual setter name

Example fix

// before
provider.invokeMethod(obj, "setPort", 8080, null); // setter is setPort(int), exact lookup ok, but setter is named setListenPort
// after
provider.invokeMethod(obj, "setListenPort", 8080, null);
Defensive patterns

Strategy: validation

Validate before calling

try {
    obj.getClass().getMethod(methodName, value.getClass());
} catch (NoSuchMethodException e) {
    throw new IllegalArgumentException("no method " + methodName + "(" + value.getClass().getName() + ") on " + obj.getClass());
}

Type guard

boolean hasSetter = java.util.Arrays.stream(obj.getClass().getMethods())
    .anyMatch(m -> m.getName().equals(methodName)
        && m.getParameterCount() == 1
        && m.getParameterTypes()[0].isAssignableFrom(value.getClass()));

Try / catch

try {
    provider.invokeMethod(obj, methodName, value, definedIn);
} catch (ObjectAccessException e) {
    Throwable cause = e.getCause();
    log.error("invoke {} failed ({}): {}", methodName, cause, cause != null ? cause.getCause() : null);
}

Prevention

When it happens

Trigger: object.getClass().getMethod(methodName, value.getClass()) finds no method with that exact signature, or method.invoke throws (wrong value type, method threw internally, access denied). Note the lookup uses value.getClass() exactly, so overloaded setters or primitive/boxed mismatches fail.

Common situations: Setter expects a primitive (setPort(int)) but a boxed Integer lookup is used (or vice versa); method name typo in configuration; setter's parameter is a supertype/interface so exact-class getMethod fails.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/73b7638950dbf0df. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/config/util/ReflectionProvider.java:121

    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();
    }

    public boolean fieldDefinedInClass(String fieldName, Class<?> type) {
        try {
            Field field = fieldDictionary.field(type, fieldName, null);
            return fieldModifiersSupported(field);
        } catch (ObjectAccessException e) {
            return false;
        }
    }

    public Field getField(Class<?> definedIn, String fieldName) {
        return fieldDictionary.field(definedIn, fieldName, null);

View on GitHub (pinned to 65f8d8beb7)