-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
Hi Spring Batch team!
First of all, thank you for your amazing work on Spring Batch 6.0
I've encountered an issue when reading JSON array files with JsonItemReader in Spring Batch 6.0 with Spring Boot 4(use jackson 3.0), and I wanted to report it in case it affects other users migrating to this version.
Bug description
JacksonJsonObjectReader(used by JsonItemReader) cannot read JSON array format [{...}, {...}] when using the default constructor in Spring Batch 6.0 with Jackson 3.0.
This appears to be caused by Jackson 3.0's change where DeserializationFeature.FAIL_ON_TRAILING_TOKENS default was changed from false to true (Jackson JSTEP-2).
When reading a JSON array, after parsing the first object, the second object's start token { is detected as a "trailing token", causing a MismatchedInputException.
Environment
- Spring Boot: 4.0.0-SNAPSHOT / spring-boot-starter-json 4.0.0-SNAPSHOT
- Spring Batch: 6.0.0-RC1
- Jackson: 3.0.1
- Java: 21
Steps to reproduce
- Create a JSON array file:
echo '[
{"command": "destroy", "cpu": 99, "status": "memory overflow"},
{"command": "explode", "cpu": 100, "status": "cpu meltdown"},
{"command": "collapse", "cpu": 95, "status": "disk burnout"}
]' > system_death.json- Configure
JsonItemReaderwith defaultJacksonJsonObjectReader:
@Bean
@StepScope
public JsonItemReader systemFailureItemReader(
@Value("#{jobParameters['inputFile']}") String inputFile) {
return new JsonItemReaderBuilder()
.name("systemFailureItemReader")
.jsonObjectReader(new JacksonJsonObjectReader<>(SystemFailure.class))
.resource(new FileSystemResource(inputFile))
.build();
}
public record SystemFailure(String command, int cpu, String status) {}- Run the job with the JSON array file
Expected behavior
JsonItemReader should successfully read all objects from the JSON array [{...}, {...}, {...}] without requiring manual Jackson configuration, as JSON arrays are a common input format for batch processing.
Actual behavior
Job fails with:
tools.jackson.databind.exc.MismatchedInputException: Trailing token (JsonToken.START_OBJECT) found after value (bound as SystemFailure): not allowed as per DeserializationFeature.FAIL_ON_TRAILING_TOKENS
Minimal Complete Reproducible example
Here's the complete configuration that reproduces the issue:
@Bean
public Job systemFailureJob(Step systemFailureStep) {
return new JobBuilder("systemFailureJob", jobRepository)
.start(systemFailureStep)
.build();
}
@Bean
public Step systemFailureStep(JsonItemReader systemFailureItemReader) {
return new StepBuilder("systemFailureStep", jobRepository)
.chunk(10)
.reader(systemFailureItemReader)
.writer(items -> items.forEach(item -> log.info("{}", item)))
.build();
}
@Bean
@StepScope
public JsonItemReader systemFailureItemReader(
@Value("#{jobParameters['inputFile']}") String inputFile) {
return new JsonItemReaderBuilder()
.name("systemFailureItemReader")
.jsonObjectReader(new JacksonJsonObjectReader<>(SystemFailure.class))
.resource(new FileSystemResource(inputFile))
.build();
}
public record SystemFailure(String command, int cpu, String status) {}Current Workaround
manually creating a JsonMapper with FAIL_ON_TRAILING_TOKENS disabled resolves the issue:
@Bean
@StepScope
public JsonItemReader systemFailureItemReader(
@Value("#{jobParameters['inputFile']}") String inputFile) {
JsonMapper jsonMapper = JsonMapper.builder()
.disable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)
.build();
JacksonJsonObjectReader jsonReader =
new JacksonJsonObjectReader<>(jsonMapper, SystemFailure.class);
return new JsonItemReaderBuilder()
.name("systemFailureItemReader")
.jsonObjectReader(jsonReader)
.resource(new FileSystemResource(inputFile))
.build();
}Suggested Solutions
I'd like to humbly suggest two possible approaches:
-
Update
JacksonJsonObjectReaderdefault constructor to create aJsonMapperwithFAIL_ON_TRAILING_TOKENSdisabled by default, since JSON array reading is a fundamental use case forJsonItemReader -
Update the documentation to clearly guide users that manual
JsonMapperconfiguration withFAIL_ON_TRAILING_TOKENSdisabled is required when reading JSON arrays in Spring Batch 6.0+
Thank you again for maintaining Spring Batch! Please let me know if you need any additional information or clarification.