spring-projects/spring-framework · error · IllegalArgumentException
Cannot create default implementation for
Error message
Cannot create default implementation for '{interfaceType.getName()}' mixin ({defaultImplType.getName()}): {ex} What it means
Thrown by DelegatePerTargetObjectIntroductionInterceptor.createNewDelegate() (also invoked once in the constructor to fail fast) when ReflectionUtils.accessibleConstructor(defaultImplType).newInstance() blows up. The interceptor needs to instantiate the default-implementation class per target object, so any failure in constructing it is wrapped in an IllegalArgumentException naming both the interfaceType and the defaultImplType.
Solutions
- Ensure defaultImplType is a concrete public class with a public no-arg constructor.
- If the delegate needs arguments, subclass DelegatePerTargetObjectIntroductionInterceptor and override getIntroductionDelegateFor / createNewDelegate to build it yourself.
- Check the wrapped cause (ex) in the stack trace to identify the exact reflection failure and address that (add constructor, loosen visibility, fix module exports).
- Verify defaultImplType actually implements interfaceType so the mixin is coherent.
Example fix
// before new DelegatePerTargetObjectIntroductionInterceptor(Lockable.class, Lockable.class); // Lockable is an interface // after new DelegatePerTargetObjectIntroductionInterceptor(LockableImpl.class, Lockable.class);
Defensive patterns
Strategy: validation
Validate before calling
Class<?> defaultImplType = ...;
int mods = defaultImplType.getModifiers();
if (defaultImplType.isInterface() || Modifier.isAbstract(mods)) {
throw new IllegalArgumentException("defaultImplType must be concrete: " + defaultImplType);
}
if (Arrays.stream(defaultImplType.getConstructors()).noneMatch(c -> c.getParameterCount() == 0)) {
throw new IllegalArgumentException("defaultImplType needs a public no-arg constructor: " + defaultImplType);
}
new DelegatePerTargetObjectIntroductionInterceptor(defaultImplType, interfaceType); Type guard
static boolean isInstantiableWithNoArg(Class<?> c) {
return !c.isInterface() && !Modifier.isAbstract(c.getModifiers())
&& Arrays.stream(c.getConstructors()).anyMatch(ct -> ct.getParameterCount() == 0);
} Prevention
- Always pass a concrete class with a public no-arg constructor as defaultImplType.
- Add a constructor sanity test that calls new DelegatePerTargetObjectIntroductionInterceptor(impl, ifc) at startup.
- Subclass and override createNewDelegate if your delegate genuinely needs arguments.
When it happens
Trigger: new DelegatePerTargetObjectIntroductionInterceptor(defaultImplType, interfaceType) where defaultImplType has no no-arg constructor, is abstract, is an interface, is a non-static inner class, has a private constructor that reflection cannot open, or its constructor throws.
Common situations: Passing an interface or abstract class as the default impl; passing a class whose only constructor requires arguments; a default impl type whose no-arg constructor throws (e.g. requires config); security manager / module access rules blocking reflective instantiation.
Related errors
- is not a valid AspectJ annotation
- AOP configuration seems to be invalid: tried calling method
- At least one handler method must be found in class
- Constructor threw exception
- Could not access method
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/31f883517c9f8b98.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/support/DelegatePerTargetObjectIntroductionInterceptor.java:139
private Object getIntroductionDelegateFor(@Nullable Object targetObject) {
synchronized (this.delegateMap) {
if (this.delegateMap.containsKey(targetObject)) {
return this.delegateMap.get(targetObject);
}
else {
Object delegate = createNewDelegate();
this.delegateMap.put(targetObject, delegate);
return delegate;
}
}
}
private Object createNewDelegate() {
try {
return ReflectionUtils.accessibleConstructor(this.defaultImplType).newInstance();
}
catch (Throwable ex) {
throw new IllegalArgumentException("Cannot create default implementation for '" +
this.interfaceType.getName() + "' mixin (" + this.defaultImplType.getName() + "): " + ex);
}
}
}
View on GitHub (pinned to 69bf83ad71)