spring-projects/spring-framework · error · IllegalArgumentException

'targetMapClass' must implement [java.util.Map]

Error message

'targetMapClass' must implement [java.util.Map]

What it means

Thrown by MapFactoryBean.setTargetMapClass() when the supplied Class does not implement java.util.Map (checked via Map.class.isAssignableFrom). MapFactoryBean instantiates this class to hold the source map entries, so the type must be a real Map. The guard prevents a later ClassCastException during instantiation and element conversion.

Solutions

  1. Set targetMapClass to a concrete java.util.Map implementation such as java.util.HashMap, java.util.TreeMap, java.util.LinkedHashMap, or java.util.concurrent.ConcurrentHashMap.
  2. Ensure the class has a public no-arg constructor.
  3. If you wanted a list/set, switch to ListFactoryBean / SetFactoryBean.

Example fix

// before (broken)
fb.setTargetMapClass(java.util.HashSet.class); // not a Map
// after
fb.setTargetMapClass(java.util.TreeMap.class);
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

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

Try / catch

try {
    fb.setTargetMapClass(clazz);
} catch (IllegalArgumentException ex) {
    if (ex.getMessage().contains("must implement")) {
        // switch to the correct factory bean or use a concrete Map class
    }
    throw ex;
}

Prevention

When it happens

Trigger: Passing a List, Set, Properties-less custom type, or arbitrary class to setTargetMapClass. XML like <property name="targetMapClass" value="java.util.ArrayList"/>. Note: java.util.Properties DOES implement Map and is accepted.

Common situations: Mixing up MapFactoryBean and ListFactoryBean/SetFactoryBean. Pointing at a custom non-Map collection. Providing an interface or abstract Map type with no no-arg constructor (caught later as a BeanInstantiationException, but worth checking).

Related errors


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

Appendix: source

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

	 * Set the source Map, typically populated via XML "map" elements.
	 */
	public void setSourceMap(Map<?, ?> sourceMap) {
		this.sourceMap = sourceMap;
	}

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


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

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

View on GitHub (pinned to 69bf83ad71)