diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/pom.xml index 142c1c6829..84c639e071 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/pom.xml +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/pom.xml @@ -26,6 +26,10 @@ false -Dfoo=bar ${project.build.sourceDirectory} + + value1 + + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/verify.groovy b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/verify.groovy index baaf7a9a59..93ce0736fa 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/verify.groovy +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-disable-fork/verify.groovy @@ -2,6 +2,6 @@ import static org.junit.Assert.assertTrue def file = new File(basedir, "build.log") assertTrue file.text.contains("I haz been run") -assertTrue file.text.contains("Fork mode disabled, ignoring JVM argument(s) [-Dfoo=bar]") +assertTrue file.text.contains("Fork mode disabled, ignoring JVM argument(s) [-Dfoo=bar -Dproperty1=value1 -Dproperty2]") assertTrue file.text.contains("Fork mode disabled, ignoring working directory configuration") diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-jvm-system-props/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-jvm-system-props/pom.xml new file mode 100644 index 0000000000..318359736c --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-jvm-system-props/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + org.springframework.boot.maven.it + run-jvmargs + 0.0.1.BUILD-SNAPSHOT + + UTF-8 + @java.version@ + @java.version@ + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + package + + run + + + -Dfoo="value 1" -Dbar=value2 + + value1 + + + + + + + + + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-jvm-system-props/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-jvm-system-props/src/main/java/org/test/SampleApplication.java new file mode 100644 index 0000000000..165822591e --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-jvm-system-props/src/main/java/org/test/SampleApplication.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.test; + +public class SampleApplication { + + public static void main(String[] args) { + String foo = System.getProperty("foo"); + if (!"value 1".equals(foo)) { + throw new IllegalStateException("foo system property mismatch (got [" + foo + "]"); + } + String bar = System.getProperty("bar"); + if (!"value2".equals(bar)) { + throw new IllegalStateException("bar system property mismatch (got [" + bar + "]"); + } + + String property1 = System.getProperty("property1"); + if (!"value1".equals(property1)) { + throw new IllegalStateException("property1 system property mismatch (got [" + property1 + "]"); + } + + String property2 = System.getProperty("property2"); + if (!"".equals(property2)) { + throw new IllegalStateException("property1 system property mismatch (got [" + property2 + "]"); + } + + System.out.println("I haz been run"); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-jvm-system-props/verify.groovy b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-jvm-system-props/verify.groovy new file mode 100644 index 0000000000..841c4a97de --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/it/run-jvm-system-props/verify.groovy @@ -0,0 +1,3 @@ +def file = new File(basedir, "build.log") +return file.text.contains("I haz been run") + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java index 3ec06db410..2923de3417 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java @@ -25,7 +25,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Resource; @@ -169,6 +171,15 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { @Parameter(property = "spring-boot.run.skip", defaultValue = "false") private boolean skip; + /** + * List of JVM system properties. System property consists of key and value + * and it will be transformed to -Dkey=value format. + * In case if value is not specified or empty only key will be provided. + * @since 2.0 + */ + @Parameter(property = "spring-boot.run.systemPropertyVariabled") + private Map systemPropertyVariables; + @Override public void execute() throws MojoExecutionException, MojoFailureException { if (this.skip) { @@ -201,7 +212,8 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { } private boolean hasJvmArgs() { - return (this.jvmArguments != null && !this.jvmArguments.isEmpty()); + return (this.jvmArguments != null && !this.jvmArguments.isEmpty()) || + (this.systemPropertyVariables != null && !this.systemPropertyVariables.isEmpty()); } private boolean hasWorkingDirectorySet() { @@ -232,8 +244,22 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { getLog().warn("Fork mode disabled, ignoring agent"); } if (hasJvmArgs()) { - getLog().warn("Fork mode disabled, ignoring JVM argument(s) [" - + this.jvmArguments + "]"); + String messageTemplate = "Fork mode disabled, ignoring JVM argument(s) [%s%s]"; + String sysPropsStr = ""; + if (this.systemPropertyVariables != null && !this.systemPropertyVariables.isEmpty()) { + sysPropsStr = this.systemPropertyVariables + .entrySet() + .stream() + .map(e -> SystemPropertyFormatter.format(e.getKey(), e.getValue())) + .collect(Collectors.joining(" ")); + } + String message = String.format( + messageTemplate, + this.jvmArguments, + sysPropsStr.isEmpty() ? sysPropsStr : " " + sysPropsStr + ); + + getLog().warn(message); } if (hasWorkingDirectorySet()) { getLog().warn("Fork mode disabled, ignoring working directory configuration"); @@ -292,7 +318,22 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @return a {@link RunArguments} defining the JVM arguments */ protected RunArguments resolveJvmArguments() { - return new RunArguments(this.jvmArguments); + final StringBuilder stringBuilder = new StringBuilder(); + if (this.jvmArguments != null) { + stringBuilder.append(this.jvmArguments); + } + if (this.systemPropertyVariables != null) { + String result = this.systemPropertyVariables + .entrySet() + .stream() + .map(e -> SystemPropertyFormatter.format(e.getKey(), e.getValue())) + .collect(Collectors.joining(" ")); + stringBuilder + .append(" ") + .append(result); + + } + return new RunArguments(stringBuilder.toString()); } private void addJvmArgs(List args) { @@ -509,4 +550,23 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { } + /** + * System properties formatter. + */ + static class SystemPropertyFormatter { + + private static final String NO_VALUE_FORMAT = "-D%s"; + private static final String KEY_VALUE_FORMAT = NO_VALUE_FORMAT + "=%s"; + + public static String format(Object key, Object value) { + if (key == null) { + return ""; + } + if (value == null || String.valueOf(value).trim().isEmpty()) { + return String.format(NO_VALUE_FORMAT, key); + } + return String.format(KEY_VALUE_FORMAT, key, value); + } + } + } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/SystemPropertyFormatterTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/SystemPropertyFormatterTests.java new file mode 100644 index 0000000000..97038d636c --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/SystemPropertyFormatterTests.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.maven; + +import org.assertj.core.api.Assertions; +import org.junit.Test; + +import org.springframework.boot.maven.AbstractRunMojo.SystemPropertyFormatter; + +/** + * Tests for {@link AbstractRunMojo.SystemPropertyFormatter} + */ +public class SystemPropertyFormatterTests { + + @Test + public void parseEmpty() throws Exception { + Assertions.assertThat(SystemPropertyFormatter.format(null, null)) + .isEqualTo(""); + } + + @Test + public void parseOnlyKey() throws Exception { + Assertions.assertThat(SystemPropertyFormatter.format("key1", null)) + .isEqualTo("-Dkey1"); + } + + @Test + public void parseKeyWithValue() throws Exception { + Assertions.assertThat(SystemPropertyFormatter.format("key1", "value1")) + .isEqualTo("-Dkey1=value1"); + } + + @Test + public void parseKeyWithEmptyValue() throws Exception { + Assertions.assertThat(SystemPropertyFormatter.format("key1", "")) + .isEqualTo("-Dkey1"); + } +}