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

  1. Ensure defaultImplType is a concrete public class with a public no-arg constructor.
  2. If the delegate needs arguments, subclass DelegatePerTargetObjectIntroductionInterceptor and override getIntroductionDelegateFor / createNewDelegate to build it yourself.
  3. 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).
  4. 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

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


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)