diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/RunIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/RunIntegrationTests.java
index ec9f69901b..12382d58ef 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/RunIntegrationTests.java
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/RunIntegrationTests.java
@@ -30,6 +30,7 @@ import static org.assertj.core.api.Assertions.contentOf;
* Integration tests for the Maven plugin's run goal.
*
* @author Andy Wilkinson
+ * @author Stephane Nicoll
*/
@ExtendWith(MavenBuildExtension.class)
class RunIntegrationTests {
@@ -107,6 +108,28 @@ class RunIntegrationTests {
.execute((project) -> assertThat(buildLog(project)).containsPattern("I haz been run from.*src.main.java"));
}
+ @TestTemplate
+ @Deprecated(since = "3.2.0", forRemoval = true)
+ void whenDirectoriesAreConfiguredTheyAreAvailableToTheApplication(MavenBuild mavenBuild) {
+ mavenBuild.project("run-directories")
+ .goals("spring-boot:run")
+ .execute((project) -> assertThat(buildLog(project)).contains("I haz been run"));
+ }
+
+ @TestTemplate
+ void whenAdditionalClasspathDirectoryIsConfiguredItsResourcesAreAvailableToTheApplication(MavenBuild mavenBuild) {
+ mavenBuild.project("run-additional-classpath-directory")
+ .goals("spring-boot:run")
+ .execute((project) -> assertThat(buildLog(project)).contains("I haz been run"));
+ }
+
+ @TestTemplate
+ void whenAdditionalClasspathFileIsConfiguredItsContentIsAvailableToTheApplication(MavenBuild mavenBuild) {
+ mavenBuild.project("run-additional-classpath-jar")
+ .goals("spring-boot:run")
+ .execute((project) -> assertThat(buildLog(project)).contains("I haz been run"));
+ }
+
@TestTemplate
@DisabledOnOs(OS.WINDOWS)
void whenAToolchainIsConfiguredItIsUsedToRunTheApplication(MavenBuild mavenBuild) {
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-directory/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-directory/pom.xml
new file mode 100644
index 0000000000..a03170ba7d
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-directory/pom.xml
@@ -0,0 +1,27 @@
+
+
+ 4.0.0
+ org.springframework.boot.maven.it
+ run-additional-classpath-directory
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+ @java.version@
+ @java.version@
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+ src/main/additional-elements/
+
+
+
+
+
+
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-directory/src/main/additional-elements/another/two.txt b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-directory/src/main/additional-elements/another/two.txt
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-directory/src/main/additional-elements/another/two.txt
@@ -0,0 +1 @@
+2
\ No newline at end of file
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-directory/src/main/additional-elements/one.txt b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-directory/src/main/additional-elements/one.txt
new file mode 100644
index 0000000000..56a6051ca2
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-directory/src/main/additional-elements/one.txt
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-directory/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-directory/src/main/java/org/test/SampleApplication.java
new file mode 100644
index 0000000000..cff7f6409b
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-directory/src/main/java/org/test/SampleApplication.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012-2020 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
+ *
+ * https://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;
+
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Scanner;
+
+public class SampleApplication {
+
+ public static void main(String[] args) {
+ if (!readContent("one.txt").contains("1")) {
+ throw new IllegalArgumentException("Invalid content for one.txt");
+ }
+ if (!readContent("another/two.txt").contains("2")) {
+ throw new IllegalArgumentException("Invalid content for another/two.txt");
+ }
+ System.out.println("I haz been run");
+ }
+
+ private static String readContent(String location) {
+ InputStream in = SampleApplication.class.getClassLoader().getResourceAsStream(location);
+ if (in == null) {
+ throw new IllegalArgumentException("Not found: '" + location + "'");
+ }
+ try (Scanner scanner = new Scanner(in, StandardCharsets.UTF_8)) {
+ return scanner.useDelimiter("\\A").next();
+ }
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-jar/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-jar/pom.xml
new file mode 100644
index 0000000000..7e1887b93f
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-jar/pom.xml
@@ -0,0 +1,27 @@
+
+
+ 4.0.0
+ org.springframework.boot.maven.it
+ run-additional-classpath-directory
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+ @java.version@
+ @java.version@
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+ src/main/additional-jar/resources-1.0.0.jar
+
+
+
+
+
+
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-jar/src/main/additional-jar/resources-1.0.0.jar b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-jar/src/main/additional-jar/resources-1.0.0.jar
new file mode 100644
index 0000000000..f6e05369c5
Binary files /dev/null and b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-jar/src/main/additional-jar/resources-1.0.0.jar differ
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-jar/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-jar/src/main/java/org/test/SampleApplication.java
new file mode 100644
index 0000000000..cff7f6409b
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-additional-classpath-jar/src/main/java/org/test/SampleApplication.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012-2020 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
+ *
+ * https://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;
+
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Scanner;
+
+public class SampleApplication {
+
+ public static void main(String[] args) {
+ if (!readContent("one.txt").contains("1")) {
+ throw new IllegalArgumentException("Invalid content for one.txt");
+ }
+ if (!readContent("another/two.txt").contains("2")) {
+ throw new IllegalArgumentException("Invalid content for another/two.txt");
+ }
+ System.out.println("I haz been run");
+ }
+
+ private static String readContent(String location) {
+ InputStream in = SampleApplication.class.getClassLoader().getResourceAsStream(location);
+ if (in == null) {
+ throw new IllegalArgumentException("Not found: '" + location + "'");
+ }
+ try (Scanner scanner = new Scanner(in, StandardCharsets.UTF_8)) {
+ return scanner.useDelimiter("\\A").next();
+ }
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-directories/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-directories/pom.xml
new file mode 100644
index 0000000000..4029ed38e4
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-directories/pom.xml
@@ -0,0 +1,27 @@
+
+
+ 4.0.0
+ org.springframework.boot.maven.it
+ run-directories
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+ @java.version@
+ @java.version@
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+ src/main/additional-elements/
+
+
+
+
+
+
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-directories/src/main/additional-elements/another/two.txt b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-directories/src/main/additional-elements/another/two.txt
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-directories/src/main/additional-elements/another/two.txt
@@ -0,0 +1 @@
+2
\ No newline at end of file
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-directories/src/main/additional-elements/one.txt b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-directories/src/main/additional-elements/one.txt
new file mode 100644
index 0000000000..56a6051ca2
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-directories/src/main/additional-elements/one.txt
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-directories/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-directories/src/main/java/org/test/SampleApplication.java
new file mode 100644
index 0000000000..cff7f6409b
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-directories/src/main/java/org/test/SampleApplication.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012-2020 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
+ *
+ * https://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;
+
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Scanner;
+
+public class SampleApplication {
+
+ public static void main(String[] args) {
+ if (!readContent("one.txt").contains("1")) {
+ throw new IllegalArgumentException("Invalid content for one.txt");
+ }
+ if (!readContent("another/two.txt").contains("2")) {
+ throw new IllegalArgumentException("Invalid content for another/two.txt");
+ }
+ System.out.println("I haz been run");
+ }
+
+ private static String readContent(String location) {
+ InputStream in = SampleApplication.class.getClassLoader().getResourceAsStream(location);
+ if (in == null) {
+ throw new IllegalArgumentException("Not found: '" + location + "'");
+ }
+ try (Scanner scanner = new Scanner(in, StandardCharsets.UTF_8)) {
+ return scanner.useDelimiter("\\A").next();
+ }
+ }
+
+}
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 c2c6a91477..9ca1409757 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
@@ -39,6 +39,7 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.toolchain.ToolchainManager;
import org.springframework.boot.loader.tools.FileUtils;
+import org.springframework.util.ObjectUtils;
/**
* Base class to run a Spring Boot application.
@@ -165,13 +166,24 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
private String mainClass;
/**
- * Additional directories besides the classes directory that should be added to the
+ * Additional directories containing classes or resources that should be added to the
* classpath.
* @since 1.0.0
+ * @deprecated since 3.2.0 for removal in 3.4.0 in favor of
+ * 'additionalClasspathElements'
*/
@Parameter(property = "spring-boot.run.directories")
+ @Deprecated(since = "3.2.0", forRemoval = true)
private String[] directories;
+ /**
+ * Additional classpath elements that should be added to the classpath. An element can
+ * be a directory with classes and resources or a jar file.
+ * @since 3.2.0
+ */
+ @Parameter(property = "spring-boot.run.additional-classpath-elements")
+ private String[] additionalClasspathElements;
+
/**
* Directory containing the classes and resource files that should be used to run the
* application.
@@ -348,7 +360,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
protected URL[] getClassPathUrls() throws MojoExecutionException {
try {
List urls = new ArrayList<>();
- addUserDefinedDirectories(urls);
+ addAdditionalClasspathLocations(urls);
addResources(urls);
addProjectClasses(urls);
addDependencies(urls);
@@ -359,10 +371,17 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
}
}
- private void addUserDefinedDirectories(List urls) throws MalformedURLException {
- if (this.directories != null) {
- for (String directory : this.directories) {
- urls.add(new File(directory).toURI().toURL());
+ @SuppressWarnings("removal")
+ private void addAdditionalClasspathLocations(List urls) throws MalformedURLException {
+ if (!ObjectUtils.isEmpty(this.directories) && !ObjectUtils.isEmpty(this.additionalClasspathElements)) {
+ throw new IllegalStateException(
+ "Either additionalClasspathElements or directories (deprecated) should be set, not both");
+ }
+ String[] elements = !ObjectUtils.isEmpty(this.additionalClasspathElements) ? this.additionalClasspathElements
+ : this.directories;
+ if (elements != null) {
+ for (String element : elements) {
+ urls.add(new File(element).toURI().toURL());
}
}
}