Open
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)
Activity
belljun3395 commentedon Mar 30, 2025
I think adding a few more conditions in
GenericConversionService#getRegisteredConverter
ConverterAdapter#matchesFallback
could fix the issue.If this is something that needs to be fixed, do you mind if I try to fix it?