With Spring Boot, you can override application properties using command line arguments like so:
java -jar my-boot.jar --my.property.name=value
This, however, fails when you try to pass an empty value:
java -jar my-boot.jar --my.property.name=
java.lang.IllegalArgumentException: Invalid argument syntax: --my.property.name=
at org.springframework.core.env.SimpleCommandLineArgsParser.parse(SimpleCommandLineArgsParser.java:75)
at org.springframework.core.env.SimpleCommandLinePropertySource.<init>(SimpleCommandLinePropertySource.java:90)
Since an empty string is a legal value for an application property, there seems to be no good reason to reject command line arguments with an empty value.
A real-world example is Kafka's ssl.endpoint.identification.algorithm which has to be set to an empty string to disable host name verification.
Comment From: sbrannen
What happens if you leave out the = sign as follows?
java -jar my-boot.jar --my.property.name
Does my.property.name then have the value of an empty string for you?
Comment From: sbrannen
FWIW, comparing the out-of-the-box implementations of CommandLinePropertySource, the following tests reveal inconsistent support for empty optional argument values.
The test for JOptCommandLinePropertySource passes.
@Test
void withOptionalArg_andArgIsEmpty() {
OptionParser parser = new OptionParser();
parser.accepts("foo").withOptionalArg();
OptionSet options = parser.parse("--foo=");
PropertySource<?> ps = new JOptCommandLinePropertySource(options);
assertThat(ps.containsProperty("foo")).isTrue();
assertThat(ps.getProperty("foo")).isEqualTo("");
}
Whereas, the test for SimpleCommandLinePropertySource fails with an exception analogous to the one mentioned in this issue's description.
@Test
void withOptionalArg_andArgIsEmpty() {
EnumerablePropertySource<?> ps = new SimpleCommandLinePropertySource("--foo=");
assertThat(ps.containsProperty("foo")).isTrue();
assertThat(ps.getProperty("foo")).isEqualTo("");
}
Thus, we could consider removing the non-empty check in org.springframework.core.env.SimpleCommandLineArgsParser.parse(String...) to make the support consistent.
Comment From: robwruck
Yes, java -jar my-boot.jar --my.property.name correctly sets the property to an empty value.
But the way to pass an argument value should not depend upon whether it is empty or not.
Actually, I created this issue because Spring Cloud Stream hits it when trying to pass empty properties while creating a binder application: https://github.com/spring-cloud/spring-cloud-stream/issues/1887
Comment From: sbrannen
Yes,
java -jar my-boot.jar --my.property.namecorrectly sets the property to an empty value.
Glad to hear that works at least as a workaround. Thanks for the feedback.
But the way to pass an argument value should not depend upon whether it is empty or not.
I agree, and we will address that for SimpleCommandLinePropertySource in Spring Framework 5.2.x.
For previous versions of Spring Framework, please use the aforementioned workaround.