diff --git a/spring-boot-docs/src/main/asciidoc/deployment.adoc b/spring-boot-docs/src/main/asciidoc/deployment.adoc index 7712762078..b49150a7b3 100644 --- a/spring-boot-docs/src/main/asciidoc/deployment.adoc +++ b/spring-boot-docs/src/main/asciidoc/deployment.adoc @@ -760,6 +760,11 @@ for Gradle and to `${project.name}` for Maven. |`confFolder` |The default value for `CONF_FOLDER`. Defaults to the folder containing the jar. +|`inlinedConfScript` +|Reference to a file script that should be inlined in the default launch script. + This can be used to set environmental variables such as `JAVA_OPTS` before + any external config files are loaded. + |`logFolder` |The default value for `LOG_FOLDER`. Only valid for an `init.d` service. diff --git a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/DefaultLaunchScript.java b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/DefaultLaunchScript.java index 3e917e54fe..c4cb0d5233 100644 --- a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/DefaultLaunchScript.java +++ b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/DefaultLaunchScript.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -23,7 +23,11 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -33,6 +37,7 @@ import java.util.regex.Pattern; * expansion of the form {{name:default}}. * * @author Phillip Webb + * @author Justin Rosenberg * @since 1.3.0 */ public class DefaultLaunchScript implements LaunchScript { @@ -44,6 +49,9 @@ public class DefaultLaunchScript implements LaunchScript { private static final Pattern PLACEHOLDER_PATTERN = Pattern .compile("\\{\\{(\\w+)(:.*?)?\\}\\}(?!\\})"); + private static final Set FILE_PATH_KEYS = Collections + .unmodifiableSet(new HashSet<>(Arrays.asList("inlinedConfScript"))); + private final String content; /** @@ -85,17 +93,26 @@ public class DefaultLaunchScript implements LaunchScript { outputStream.flush(); } - private String expandPlaceholders(String content, Map properties) { + private String expandPlaceholders(String content, Map properties) + throws IOException { StringBuffer expanded = new StringBuffer(); Matcher matcher = PLACEHOLDER_PATTERN.matcher(content); while (matcher.find()) { String name = matcher.group(1); - String value = matcher.group(2); + final String value; + String defaultValue = matcher.group(2); if (properties != null && properties.containsKey(name)) { - value = (String) properties.get(name); + Object propertyValue = properties.get(name); + if (FILE_PATH_KEYS.contains(name)) { + value = parseFilePropertyValue(properties.get(name)); + } + else { + value = propertyValue.toString(); + } } else { - value = (value == null ? matcher.group(0) : value.substring(1)); + value = (defaultValue == null ? matcher.group(0) + : defaultValue.substring(1)); } matcher.appendReplacement(expanded, value.replace("$", "\\$")); } @@ -103,6 +120,15 @@ public class DefaultLaunchScript implements LaunchScript { return expanded.toString(); } + private String parseFilePropertyValue(Object propertyValue) throws IOException { + if (propertyValue instanceof File) { + return loadContent((File) propertyValue); + } + else { + return loadContent(new File(propertyValue.toString())); + } + } + @Override public byte[] toByteArray() { return this.content.getBytes(UTF_8); diff --git a/spring-boot-tools/spring-boot-loader-tools/src/main/resources/org/springframework/boot/loader/tools/launch.script b/spring-boot-tools/spring-boot-loader-tools/src/main/resources/org/springframework/boot/loader/tools/launch.script old mode 100755 new mode 100644 index c4124cd297..cd30219aa4 --- a/spring-boot-tools/spring-boot-loader-tools/src/main/resources/org/springframework/boot/loader/tools/launch.script +++ b/spring-boot-tools/spring-boot-loader-tools/src/main/resources/org/springframework/boot/loader/tools/launch.script @@ -46,6 +46,9 @@ done jarfolder="$( (cd "$(dirname "$jarfile")" && pwd -P) )" cd "$WORKING_DIR" || exit 1 +# Inline script specified in build properties +{{inlinedConfScript:}} + # Source any config file configfile="$(basename "${jarfile%.*}.conf")" diff --git a/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/DefaultLaunchScriptTests.java b/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/DefaultLaunchScriptTests.java index 2582cba95c..71123ae25f 100644 --- a/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/DefaultLaunchScriptTests.java +++ b/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/DefaultLaunchScriptTests.java @@ -17,6 +17,7 @@ package org.springframework.boot.loader.tools; import java.io.File; +import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -33,6 +34,7 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Phillip Webb * @author Andy Wilkinson + * @author Justin Rosenberg */ public class DefaultLaunchScriptTests { @@ -126,6 +128,14 @@ public class DefaultLaunchScriptTests { assertThatPlaceholderCanBeReplaced("stopWaitTime"); } + @Test + public void inlinedConfScriptFileLoad() throws IOException { + DefaultLaunchScript script = new DefaultLaunchScript(null, + createProperties("inlinedConfScript:src/test/resources/example.script")); + String content = new String(script.toByteArray()); + assertThat(content).contains("FOO=BAR"); + } + @Test public void defaultForUseStartStopDaemonIsTrue() throws Exception { DefaultLaunchScript script = new DefaultLaunchScript(null, null); @@ -185,6 +195,15 @@ public class DefaultLaunchScriptTests { assertThat(content).isEqualTo("hello"); } + @Test + public void expandVariablesCanDefaultToBlank() throws Exception { + File file = this.temporaryFolder.newFile(); + FileCopyUtils.copy("s{{p:}}{{r:}}ing".getBytes(), file); + DefaultLaunchScript script = new DefaultLaunchScript(file, null); + String content = new String(script.toByteArray()); + assertThat(content).isEqualTo("sing"); + } + @Test public void expandVariablesWithDefaultsOverride() throws Exception { File file = this.temporaryFolder.newFile(); diff --git a/spring-boot-tools/spring-boot-loader-tools/src/test/resources/example.script b/spring-boot-tools/spring-boot-loader-tools/src/test/resources/example.script new file mode 100644 index 0000000000..15c36f50ef --- /dev/null +++ b/spring-boot-tools/spring-boot-loader-tools/src/test/resources/example.script @@ -0,0 +1 @@ +FOO=BAR \ No newline at end of file