spring-projects / spring-projects/spring-framework

`GenericConversionService` selects incorrect converter for `String` to `List<String>` conversion

Open
#34,685 1 comment 0 reactions 1 assignee View on GitHub

@sdeleuze is already working on this.

Since Jun 17, 2025.

in: core status: waiting-for-internal-feedback status: waiting-for-triage
Dominant language
Java
Stars
60.2k
Forks
38.8k
Avg merge
5d 2h
Merged PRs (30d)
27

Description

This issue is related to #34535 and #34298.

Converter<String, List<? extends Map<String, ?>>> is incorrectly selected when converting a String to a List<String>.

The following reproducer test fails on all 6.2.x versions except 6.2.3:

package com.example;

import org.junit.jupiter.api.Test;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.core.convert.support.StringToCollectionConverter;

import java.util.List;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;

class GenericConversionServiceTests {

	private final GenericConversionService conversionService = new GenericConversionService();

	@Test
	@SuppressWarnings("unchecked")
	void stringToListOfString() {
		conversionService.addConverter(new StringToCollectionConverter(conversionService));
		conversionService.addConverter(new StringToListOfMapConverter());

		List<String> result = (List<String>) conversionService.convert("foo,bar",
				TypeDescriptor.valueOf(String.class),
				TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(String.class))
		);

		assertThat(result.get(0)).isEqualTo("foo");
	}

	private static class StringToListOfMapConverter implements Converter<String, List<? extends Map<String, ?>>> {

		@Override
		public List<? extends Map<String, ?>> convert(String source) {
			return List.of(Map.of("bar", source));
		}
	}

	// Using this version of the converter also results in a failure
	private static class StringToListOfMapConverterWithoutWildcard implements Converter<String, List<Map<String, ?>>> {

		@Override
		public List<Map<String, ?>> convert(String source) {
			return List.of(Map.of("bar", source));
		}
	}
}

The exception shows that the StringToListOfMapConverter converter was chosen instead of expected StringToCollectionConverter:

class java.util.ImmutableCollections$Map1 cannot be cast to class java.lang.String (java.util.ImmutableCollections$Map1 and java.lang.String are in module java.base of loader 'bootstrap')
java.lang.ClassCastException: class java.util.ImmutableCollections$Map1 cannot be cast to class java.lang.String (java.util.ImmutableCollections$Map1 and java.lang.String are in module java.base of loader 'bootstrap')
	at org.springframework.core.convert.support.GenericConversionServiceTests.stringToListOfString(GenericConversionServiceTests.java:28)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.