Repository navigation
[Enhancement] Custom converters registered with supportExcelTypeKey() == null never apply when reading #1085
Description
Search before asking
- I searched in the issues and found nothing similar.
Fesod version
2.0.2-incubating (the code path is unchanged on current main)
JDK version
1.8
Operating system
Windows 10
Minimal reproduce step
Register a custom converter whose supportExcelTypeKey() returns null (the wildcard
contract: match every cell data type), then read a file whose cells are plain strings:
public static class BooleanYesNoConverter implements Converter<Boolean> {
@Override
public Class<?> supportJavaTypeKey() {
return Boolean.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return null; // wildcard: match every cell type
}
@Override
public Boolean convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
return "yes".equalsIgnoreCase(cellData.getStringValue());
}
}
// the file contains STRING cells "yes" and "no"
FesodSheet.read(file, BooleanReadData.class, listener)
.registerConverter(new BooleanYesNoConverter())
.sheet()
.doReadSync();Current behavior
The wildcard converter is silently ignored on the read path. ConverterUtils#convertToJavaObject
looks the converter up with the concrete cell type key (Boolean, STRING); a converter registered
under the wildcard key (Boolean, null) never matches, so the built-in BooleanStringConverter
takes over and Boolean.valueOf("yes") returns false — the row is silently read as
flag = false, no warning is logged.
Two more notes:
- Control case: registering the identical converter with an explicit
CellDataTypeEnum.STRINGkey works on read — only the wildcard registration is broken. - For types/classes without any built-in concrete-key converter, the read fails with
ExcelDataConvertException: Converter not foundinstead.
The same registration works on the write path for xlsx, where the lookup key is
(Boolean, null) — so read and write disagree about the wildcard contract. See #1045 /
#1056 (write/CSV flavor of the same key mismatch, fix in progress in PR #1069); this report
covers the read path, which that PR does not touch.
Expected behavior
Custom converters registered with supportExcelTypeKey() == null apply on read as well,
consistent with the wildcard contract and with the write path.
Root cause
- Registration (
AbstractReadHolder#initConverterMap): custom converters are registered only
under(supportJavaTypeKey(), supportExcelTypeKey()), so a wildcard registration lands on
(Boolean, null). - Lookup (
ConverterUtils#convertToJavaObjectandConverterUtils#convertToStringMap): a
single exactconverterMap.get(buildKey(clazz, cellData.getType()))with a concrete type and
no fallback.
Suggested fix
Either option works; happy to implement either in a PR:
- Fallback lookup (recommended): in
ConverterUtils, when the exact-key lookup misses and
the cell type is non-null, retry once with the wildcard key(clazz, null)before failing.
On the read side default converters are registered only under concrete keys
(DefaultConverterLoader#putAllConverter), so the fallback can only hit user wildcard
registrations: no shadowing, explicit registrations keep priority, and behavior only changes
where reading fails or returns wrong data today. - Registration expansion (mirrors PR fix: honor wildcard-key custom converters when writing CSV (#1045) (#1056) #1069 on the write side): additionally register
null-key customs under every concrete cell type. Consistent with the write-side fix, but it
introduces order-dependent overwriting between wildcard and explicit registrations.
Are you willing to submit a PR?
- I'm willing to submit a PR! (fix + round-trip regression tests are already prepared and
verified: the wildcard-read case fails on current main and passes with the fix)
Activity
BigDataDZ commentedon Sep 8, 2026
Hi, I'd like to take this one.
I've reproduced it on current
mainwith a round-trip test: a wildcard (supportExcelTypeKey() == null)Boolean converter reads a
"yes"cell asfalsebecause the built-inBooleanStringConvertertakesover silently — while the identical converter registered with an explicit
STRINGkey works.A fix together with regression tests is already prepared (the wildcard-read case fails on current main
and passes with the fix), following option 1 (fallback lookup in
ConverterUtils) as described above.If maintainers would rather stay consistent with the registration-expansion approach of #1069 on the write
side, I'm happy to switch to option 2 instead.
Will open the PR right away either way.
bengbengbalabalabeng commentedon Sep 9, 2026
Looking at the design of spreadsheet reading, resolving converters strictly via (JavaType + CellDataType) is the expected standard behavior rather than a bug, as the cell data type is always concrete during parsing.
Introducing
nullas a wildcard fallback is more of anEnhancement. Could you please update the title of this Issue and PR from [Bug] to [Enhancement]?[-][Bug] Custom converters registered with supportExcelTypeKey() == null never apply when reading[/-][+][Enhancement] Custom converters registered with supportExcelTypeKey() == null never apply when reading[/+]BigDataDZ commentedon Sep 10, 2026
Thanks for the clarification @bengbengbalabalabeng — agreed, with the cell data type always
concrete during parsing, the strict
(JavaType + CellDataType)resolution is by design and thewildcard fallback is better framed as an enhancement.
Both titles are updated ([Enhancement] here,
feat:on PR #1086, including the branch commit).The PR is ready for re-review.