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()); } } }