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.name correctly 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.