Skip to content

Commit 36c4fc1

Browse files
Wordbefmbenhassine
authored andcommitted
Fix parameter value truncation in CommandLineJobOperator
CommandLineJobOperator.parse() uses String.split("=") which splits on every "=" character, causing parameter values containing "=" to be truncated. Additionally, parameters without "=" cause an ArrayIndexOutOfBoundsException. Use StringUtils.splitArrayElementsIntoProperties for consistency with JobLauncherApplicationRunner and the deprecated CommandLineJobRunner. Resolves #5295 Signed-off-by: Wordbe <seonghojin3@gmail.com>
1 parent 2effdc0 commit 36c4fc1

2 files changed

Lines changed: 58 additions & 8 deletions

File tree

spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/CommandLineJobOperator.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3535
import org.springframework.core.log.LogAccessor;
3636
import org.springframework.util.Assert;
37+
import org.springframework.util.StringUtils;
3738

3839
import static org.springframework.batch.core.launch.support.ExitCodeMapper.JVM_EXITCODE_COMPLETED;
3940
import static org.springframework.batch.core.launch.support.ExitCodeMapper.JVM_EXITCODE_GENERIC_ERROR;
@@ -403,13 +404,9 @@ public static void main(String[] args) {
403404
System.exit(exitCode);
404405
}
405406

406-
private static Properties parse(List<String> jobParameters) {
407-
Properties properties = new Properties();
408-
for (String jobParameter : jobParameters) {
409-
String[] tokens = jobParameter.split("=");
410-
properties.put(tokens[0], tokens[1]);
411-
}
412-
return properties;
407+
static Properties parse(List<String> jobParameters) {
408+
Properties properties = StringUtils.splitArrayElementsIntoProperties(jobParameters.toArray(new String[0]), "=");
409+
return (properties != null) ? properties : new Properties();
413410
}
414411

415412
}

spring-batch-core/src/test/java/org/springframework/batch/core/launch/support/CommandLineJobOperatorTests.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2025 the original author or authors.
2+
* Copyright 2025-2026 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.batch.core.launch.support;
1717

18+
import java.util.List;
1819
import java.util.Properties;
1920

2021
import org.junit.jupiter.api.Assertions;
@@ -187,6 +188,58 @@ void abandonJobExecutionNotStopped() throws Exception {
187188
Mockito.verify(jobOperator, Mockito.never()).abandon(jobExecution);
188189
}
189190

191+
@Test
192+
void parseWithParameterContainingEqualsSign() {
193+
// given
194+
List<String> jobParameters = List.of("url=http://example.com?id=123");
195+
196+
// when
197+
Properties properties = CommandLineJobOperator.parse(jobParameters);
198+
199+
// then
200+
Assertions.assertEquals(1, properties.size());
201+
Assertions.assertEquals("http://example.com?id=123", properties.get("url"));
202+
}
203+
204+
@Test
205+
void parseWithMultipleParameters() {
206+
// given
207+
List<String> jobParameters = List.of("name=test", "count=10");
208+
209+
// when
210+
Properties properties = CommandLineJobOperator.parse(jobParameters);
211+
212+
// then
213+
Assertions.assertEquals(2, properties.size());
214+
Assertions.assertEquals("test", properties.get("name"));
215+
Assertions.assertEquals("10", properties.get("count"));
216+
}
217+
218+
@Test
219+
void parseWithParameterContainingMultipleEqualsSign() {
220+
// given
221+
List<String> jobParameters = List.of("url=http://example.com?id=123&name=test");
222+
223+
// when
224+
Properties properties = CommandLineJobOperator.parse(jobParameters);
225+
226+
// then
227+
Assertions.assertEquals(1, properties.size());
228+
Assertions.assertEquals("http://example.com?id=123&name=test", properties.get("url"));
229+
}
230+
231+
@Test
232+
void parseWithInvalidParameter() {
233+
// given
234+
List<String> jobParameters = List.of("invalidParam");
235+
236+
// when
237+
Properties properties = CommandLineJobOperator.parse(jobParameters);
238+
239+
// then
240+
Assertions.assertTrue(properties.isEmpty());
241+
}
242+
190243
@Test
191244
void recover() {
192245
// given

0 commit comments

Comments
 (0)