MyCATApache/Mycat-Server · error · ObjectAccessException

Cannot construct

Error message

Cannot construct ${type}

What it means

ReflectionProvider.newInstance wraps InstantiationException in ObjectAccessException('Cannot construct <type>'). InstantiationException occurs when the resolved constructor is abstract-interface instantiation, or the constructor is not accessible/ class is abstract, etc. The root cause is reflection being unable to actually run the constructor.

Solutions

  1. Replace the abstract class/interface reference in config with a concrete instantiable class
  2. Make the class concrete (remove abstract modifier) if it should be instantiated
  3. Check constructor visibility/accessibility and that the class has a workable no-arg constructor

Example fix

// before (config)
<class>com.example.AbstractHandler</class>
// after
<class>com.example.DefaultHandler</class>
Defensive patterns

Strategy: type-guard

Validate before calling

if (Modifier.isAbstract(type.getModifiers()) || type.isInterface()) throw new ConfigException(type.getName() + " is abstract; configure a concrete subclass");

Type guard

boolean concrete = type != null && !type.isInterface() && !Modifier.isAbstract(type.getModifiers());

Try / catch

try { return ReflectionProvider.newInstance(type); } catch (ObjectAccessException e) { throw new ConfigException("cannot instantiate " + type.getName() + ": use a concrete class", e); }

Prevention

When it happens

Trigger: Calling newInstance(type) on an abstract class or interface that (surprisingly) passed the constructor scan, or where c[i].newInstance() fails with InstantiationException; constructor not visible to the caller's classloader context.

Common situations: Configuring an abstract base class or interface name where a concrete implementation class is expected (e.g. a <class> attribute pointing at an interface); class made abstract in a refactor while old config still references it.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

    public Object newInstance(Class<?> type) {
        try {
            Constructor<?>[] c = type.getDeclaredConstructors();
            for (int i = 0; i < c.length; i++) {
                if (c[i].getParameterTypes().length == 0) {
                    if (!Modifier.isPublic(c[i].getModifiers())) {
                        c[i].setAccessible(true);
                    }
                    return c[i].newInstance(new Object[0]);
                }
            }
            if (Serializable.class.isAssignableFrom(type)) {
                return instantiateUsingSerialization(type);
            } else {
                throw new ObjectAccessException("Cannot construct " + type.getName()
                        + " as it does not have a no-args constructor");
            }
        } catch (InstantiationException e) {
            throw new ObjectAccessException("Cannot construct " + type.getName(), e);
        } catch (IllegalAccessException e) {
            throw new ObjectAccessException("Cannot construct " + type.getName(), e);
        } catch (InvocationTargetException e) {
            if (e.getTargetException() instanceof RuntimeException) {
                throw (RuntimeException) e.getTargetException();
            } else if (e.getTargetException() instanceof Error) {
                throw (Error) e.getTargetException();
            } else {
                throw new ObjectAccessException("Constructor for " + type.getName() + " threw an exception",
                        e.getTargetException());
            }
        }
    }

    public void visitSerializableFields(Object object, Visitor visitor) {
        for (Iterator<Field> iterator = fieldDictionary.serializableFieldsFor(object.getClass()); iterator.hasNext();) {
            Field field = iterator.next();
            if (!fieldModifiersSupported(field)) {

View on GitHub (pinned to 65f8d8beb7)