MyCATApache/Mycat-Server · error · ObjectAccessException

Cannot construct as it does not have a no-args constructor

Error message

Cannot construct ${type} as it does not have a no-args constructor

What it means

ReflectionProvider.newInstance tries each declared constructor in turn; if none is a no-args constructor it falls back to serialization-based instantiation for Serializable types, and otherwise throws ObjectAccessException. The class cannot be instantiated reflectively without a no-arg constructor (and is not Serializable).

Solutions

  1. Add a public no-arg constructor to the target class
  2. Make the class implement java.io.Serializable so the serialization fallback can be used
  3. If instantiation is intentional with arguments, call a different factory/API that supplies constructor arguments

Example fix

// before
public class DataSourceCfg { public DataSourceCfg(String host) {...} }
// after
public class DataSourceCfg { public DataSourceCfg() {} public DataSourceCfg(String host) {...} }
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean canNewInstance(Class<?> t) {
  if (t.isInterface() || Modifier.isAbstract(t.getModifiers())) return false;
  try { t.getDeclaredConstructor(); return true; } catch (NoSuchMethodException e) { return Serializable.class.isAssignableFrom(t); }
}

Type guard

boolean instantiable = c != null && !c.isInterface() && !Modifier.isAbstract(c.getModifiers());

Try / catch

try { return ReflectionProvider.newInstance(type); } catch (ObjectAccessException e) { throw new ConfigException("bean " + type.getName() + " needs a public no-arg constructor", e); }

Prevention

When it happens

Trigger: Calling newInstance(type) on a class that only defines parameterized constructors, is not Serializable, and has no accessible no-arg constructor — commonly during config-bean deserialization.

Common situations: Bean classes written with required-argument constructors (e.g. immutable beans) then fed to the XML/reflection config loader; inner/non-static classes whose constructors take an enclosing instance; adding a constructor to a previously default-constructed bean.

Related errors


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

Appendix: source

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

    private transient Map<Class<?>, byte[]> serializedDataCache = Collections
            .synchronizedMap(new HashMap<Class<?>, byte[]>());
    private transient FieldDictionary fieldDictionary = new FieldDictionary();

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

View on GitHub (pinned to 65f8d8beb7)