spring-projects/spring-framework · error · IllegalArgumentException

[{ifc.getName()}] is not an interface

Error message

[{ifc.getName()}] is not an interface

What it means

AdvisedSupport.addInterface() (line 231) registers an interface to be proxied. It guards with ifc.isInterface() (line 233) and throws if a concrete class (or enum, etc.) is passed. JDK/CGLIB proxies expose interfaces, so adding a non-interface is a user error.

Source

Thrown at spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java:234

	/**
	 * Set the interfaces to be proxied.
	 */
	public void setInterfaces(Class<?>... interfaces) {
		Assert.notNull(interfaces, "Interfaces must not be null");
		this.interfaces.clear();
		for (Class<?> ifc : interfaces) {
			addInterface(ifc);
		}
	}

	/**
	 * Add a new proxied interface.
	 * @param ifc the additional interface to proxy
	 */
	public void addInterface(Class<?> ifc) {
		Assert.notNull(ifc, "Interface must not be null");
		if (!ifc.isInterface()) {
			throw new IllegalArgumentException("[" + ifc.getName() + "] is not an interface");
		}
		if (!this.interfaces.contains(ifc)) {
			this.interfaces.add(ifc);
			adviceChanged();
		}
	}

	/**
	 * Remove a proxied interface.
	 * <p>Does nothing if the given interface isn't proxied.
	 * @param ifc the interface to remove from the proxy
	 * @return {@code true} if the interface was removed; {@code false}
	 * if the interface was not found and hence could not be removed
	 */
	public boolean removeInterface(Class<?> ifc) {
		return this.interfaces.remove(ifc);
	}

View on GitHub (pinned to 69bf83ad71)

Solutions

  1. Pass an actual interface type, e.g. addInterface(MyService.class) where MyService is an interface
  2. If you intended to proxy a concrete class, use setProxyTargetClass(true) / proxyTargetClass="true" instead of adding the class as an interface
  3. Double-check the types array passed to setInterfaces(...) contains only interfaces

Example fix

// before
advised.addInterface(MyServiceImpl.class);

// after
advised.addInterface(MyService.class);  // MyService is the interface
Defensive patterns

Strategy: type-guard

Validate before calling

if (ifc != null && !ifc.isInterface()) {
  throw new IllegalStateException(ifc.getName() + " is not an interface; use proxyTargetClass for class proxying");
}

Type guard

private static boolean isProxiableInterface(Class<?> ifc) {
  return ifc != null && ifc.isInterface();
}

Prevention

When it happens

Trigger: Calling addInterface(SomeConcreteClass.class) or setInterfaces(SomeConcreteClass.class); XML/java config that lists a class instead of an interface among proxyInterfaces.

Common situations: Confusing the proxy-target-class (CGLIB subclassing) concept with the interface list; passing the implementation class where the interface was intended; migrating from proxyTargetClass=true and mistakenly adding the impl class to setInterfaces.

Related errors


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