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
- Add a public no-arg constructor to the target class
- Make the class implement java.io.Serializable so the serialization fallback can be used
- 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
- Give every config bean a public no-arg constructor
- Keep bean classes top-level and static (avoid inner classes)
- Don't make configurable bean classes abstract
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
- Cannot construct
- Constructor for threw an exception
- Cannot create by JDK serialization
- rule function must implements
- No such field .
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)