apache/iceberg · error · IllegalArgumentException
Cannot initialize LockManager, missing no-arg constructor: %
Error message
Cannot initialize LockManager, missing no-arg constructor: %s
What it means
LockManagers.loadLockManager builds the configured LockManager implementation via DynConstructors expecting a no-arg constructor. If the class exists but has none, it throws IllegalArgumentException naming the implementation class.
Source
Thrown at core/src/main/java/org/apache/iceberg/util/LockManagers.java:62
public static LockManager defaultLockManager() {
return LOCK_MANAGER_DEFAULT;
}
public static LockManager from(Map<String, String> properties) {
if (properties.containsKey(CatalogProperties.LOCK_IMPL)) {
return loadLockManager(properties.get(CatalogProperties.LOCK_IMPL), properties);
} else {
return defaultLockManager();
}
}
private static LockManager loadLockManager(String impl, Map<String, String> properties) {
DynConstructors.Ctor<LockManager> ctor;
try {
ctor = DynConstructors.builder(LockManager.class).hiddenImpl(impl).buildChecked();
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException(
String.format("Cannot initialize LockManager, missing no-arg constructor: %s", impl), e);
}
LockManager lockManager;
try {
lockManager = ctor.newInstance();
} catch (ClassCastException e) {
throw new IllegalArgumentException(
String.format("Cannot initialize LockManager, %s does not implement LockManager.", impl),
e);
}
lockManager.initialize(properties);
return lockManager;
}
public abstract static class BaseLockManager implements LockManager {
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Add a public no-arg constructor to the LockManager implementation and move logic into initialize(Map<String,String>)
- Verify lock.impl points to the correct, fully-qualified concrete class
- Fall back to the default in-memory lock manager for single-JVM use
Example fix
// before
class MyLockManager implements LockManager {
MyLockManager(String path) { ... }
}
// after
class MyLockManager implements LockManager {
public MyLockManager() { }
@Override
public void initialize(Map<String, String> properties) { this.path = properties.get("path"); }
} Defensive patterns
Strategy: try-catch
Validate before calling
Class<?> c = Class.forName(impl); if (!LockManager.class.isAssignableFrom(c)) throw new IllegalArgumentException(impl + " is not a LockManager"); if (c.getDeclaredConstructor() == null || !java.lang.reflect.Modifier.isPublic(c.getDeclaredConstructor().getModifiers())) throw new IllegalArgumentException(impl + " needs a public no-arg constructor");
Try / catch
try { LockManagers.from(properties); } catch (IllegalArgumentException e) { /* fall back to default lock manager */ } Prevention
- Give every custom LockManager a public no-arg constructor
- Put config-driven setup in initialize(Map), not constructors
- Unit-test LockManagers.from() with your configured class
When it happens
Trigger: Setting lock.impl to a LockManager class that only defines parameterized constructors (custom lock managers typically require a no-arg ctor because initialize(properties) is called separately).
Common situations: Custom LockManager implementations that put initialization logic in a constructor with arguments; inner classes without a public no-arg constructor; copying an example class whose constructor signature was changed.
Related errors
- Cannot initialize LockManager, %s does not implement LockMan
- Cannot initialize Catalog implementation %s: %s
- Cannot initialize FileIO implementation %s: %s
- Cannot initialize MetricsReporter, %s does not implement Met
- Class %s does not implement DynamicRecordGeneratorSQL
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/c1368b341f512b8d.
Report an issue: GitHub.