spring-projects/spring-framework · error · IllegalArgumentException

IntroductionInfo defines no interfaces to introduce

Error message

IntroductionInfo defines no interfaces to introduce: {introductionInfo}

What it means

Thrown by DefaultIntroductionAdvisor constructor (line 71-76) when the supplied IntroductionInfo returns an empty array from getInterfaces(). An introduction must add at least one interface to the proxy so the proxy can implement new behavior; an IntroductionInfo describing zero interfaces is meaningless and rejected with an IllegalArgumentException.

Solutions

  1. Make your IntroductionInfo.getInterfaces() return at least one interface that the introduction advice actually implements.
  2. Extend DelegatingIntroductionInterceptor and implement at least one marker/interface method so it exposes that interface.
  3. If you only need plain advice (not an introduction), use DefaultPointcutAdvisor instead of DefaultIntroductionAdvisor.

Example fix

// before
public class EmptyIntro implements IntroductionInfo {
    public Class<?>[] getInterfaces() { return new Class<?>[0]; }
}
new DefaultIntroductionAdvisor(advice, new EmptyIntro()); // fails

// after
public class NamedBeanIntro extends DelegatingIntroductionInterceptor
        implements NamedBean {
    public String getBeanName() { return "b"; }
}
new DefaultIntroductionAdvisor(new NamedBeanIntro());
Defensive patterns

Strategy: validation

Validate before calling

IntroductionInfo info = /* ... */;
if (info.getInterfaces() == null || info.getInterfaces().length == 0) {
    throw new IllegalArgumentException("IntroductionInfo exposes no interfaces");
}

Type guard

static boolean hasInterfaces(IntroductionInfo info) {
    Class<?>[] c = info.getInterfaces();
    return c != null && c.length > 0;
}

Prevention

When it happens

Trigger: Constructing 'new DefaultIntroductionAdvisor(advice, introductionInfo)' where the IntroductionInfo.getInterfaces() returns an empty Class[] array. Common with a DelegatingIntroductionInterceptor subclass whose getInterfaces() was overridden/implemented to return nothing, or an IntroductionInfo built from a class exposing no interfaces.

Common situations: Implementing IntroductionInfo and forgetting to populate the interface list. Subclassing DelegatingIntroductionInterceptor but the target introduces no interfaces. Passing an IntroductionInfo whose getInterfaces() is computed dynamically and yields empty under some configuration.

Related errors


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/c29d18bad3815b7a. Report an issue: GitHub.

Appendix: source

Thrown at spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java:74

	 * @see #addInterface
	 */
	public DefaultIntroductionAdvisor(Advice advice) {
		this(advice, (advice instanceof IntroductionInfo introductionInfo ? introductionInfo : null));
	}

	/**
	 * Create a DefaultIntroductionAdvisor for the given advice.
	 * @param advice the Advice to apply
	 * @param introductionInfo the IntroductionInfo that describes
	 * the interface to introduce (may be {@code null})
	 */
	public DefaultIntroductionAdvisor(Advice advice, @Nullable IntroductionInfo introductionInfo) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
		if (introductionInfo != null) {
			Class<?>[] introducedInterfaces = introductionInfo.getInterfaces();
			if (introducedInterfaces.length == 0) {
				throw new IllegalArgumentException(
						"IntroductionInfo defines no interfaces to introduce: " + introductionInfo);
			}
			for (Class<?> ifc : introducedInterfaces) {
				addInterface(ifc);
			}
		}
	}

	/**
	 * Create a DefaultIntroductionAdvisor for the given advice.
	 * @param advice the Advice to apply
	 * @param ifc the interface to introduce
	 */
	public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class<?> ifc) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
		addInterface(ifc);
	}

View on GitHub (pinned to 69bf83ad71)