spring-projects/spring-framework · error · IllegalArgumentException

'targetListClass' must implement [java.util.List]

Error message

'targetListClass' must implement [java.util.List]

What it means

Thrown by ListFactoryBean.setTargetListClass() when the supplied Class does not implement java.util.List (checked via List.class.isAssignableFrom). ListFactoryBean must instantiate the class to hold the list elements, so it requires a concrete List type. This is a type-safety guard so the BeanUtils.instantiateClass call later cannot fail with a ClassCastException.

Solutions

  1. Change targetListClass to a concrete java.util.List implementation such as java.util.ArrayList, java.util.LinkedList, or java.util.concurrent.CopyOnWriteArrayList.
  2. If you actually want a Set, switch to org.springframework.beans.factory.config.SetFactoryBean instead.
  3. Verify the class has a public no-arg constructor (BeanUtils.instantiateClass needs one).

Example fix

// before (broken)
fb.setTargetListClass(java.util.HashSet.class); // not a List
// after
fb.setTargetListClass(java.util.LinkedList.class);
Defensive patterns

Strategy: type-guard

Validate before calling

Class<?> c = /* from config */;
if (c != null && !List.class.isAssignableFrom(c)) {
    throw new IllegalStateException(c.getName() + " is not a java.util.List");
}
fb.setTargetListClass((Class<? extends List>) c);

Type guard

static boolean isConcreteList(Class<?> c) {
    return c != null && List.class.isAssignableFrom(c)
        && !Modifier.isAbstract(c.getModifiers()) && !c.isInterface();
}

Try / catch

try {
    fb.setTargetListClass(clazz);
} catch (IllegalArgumentException ex) {
    if (ex.getMessage().contains("must implement")) {
        // wrong collection type: log and use a SetFactoryBean instead, or switch to ArrayList
    }
    throw ex;
}

Prevention

When it happens

Trigger: Passing a Set type (java.util.HashSet), a Queue, a Map, or any arbitrary class to setTargetListClass. XML config like <property name="targetListClass" value="java.util.HashSet"/>. Passing an abstract List type or one with no no-arg constructor also surfaces nearby (during instantiation, not here).

Common situations: Confusing ListFactoryBean with SetFactoryBean and pointing it at a Set. Copy-pasting a MapFactoryBean/MapFactoryBean definition into a ListFactoryBean and forgetting to change the class. Specifying a custom collection that extends Collection but not List.

Related errors


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

Appendix: source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/config/ListFactoryBean.java:64

	 * Set the source List, typically populated via XML "list" elements.
	 */
	public void setSourceList(List<?> sourceList) {
		this.sourceList = sourceList;
	}

	/**
	 * Set the class to use for the target List. Can be populated with a fully
	 * qualified class name when defined in a Spring application context.
	 * <p>Default is a {@code java.util.ArrayList}.
	 * @see java.util.ArrayList
	 */
	@SuppressWarnings("rawtypes")
	public void setTargetListClass(@Nullable Class<? extends List> targetListClass) {
		if (targetListClass == null) {
			throw new IllegalArgumentException("'targetListClass' must not be null");
		}
		if (!List.class.isAssignableFrom(targetListClass)) {
			throw new IllegalArgumentException("'targetListClass' must implement [java.util.List]");
		}
		this.targetListClass = targetListClass;
	}


	@Override
	@SuppressWarnings("rawtypes")
	public Class<List> getObjectType() {
		return List.class;
	}

	@Override
	@SuppressWarnings("unchecked")
	protected List<Object> createInstance() {
		if (this.sourceList == null) {
			throw new IllegalArgumentException("'sourceList' is required");
		}
		List<Object> result = null;

View on GitHub (pinned to 69bf83ad71)