Rename run goal's directories property to additionalClasspathElements

This clarifies what used to be called "directories" as both a directory
and a jar file can be provided. A directory with `/*` would also load
all the jar files from that directory.

The "directories" property has been deprecated as a result.

Closes gh-35179
This commit is contained in:
Stephane Nicoll 2023-08-03 16:22:07 +02:00
parent c16fbf657f
commit f34dc05452
13 changed files with 268 additions and 6 deletions

View File

@ -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) {

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot.maven.it</groupId>
<artifactId>run-additional-classpath-directory</artifactId>
<version>0.0.1.BUILD-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>@java.version@</maven.compiler.source>
<maven.compiler.target>@java.version@</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>@project.groupId@</groupId>
<artifactId>@project.artifactId@</artifactId>
<version>@project.version@</version>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>src/main/additional-elements/</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

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

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot.maven.it</groupId>
<artifactId>run-additional-classpath-directory</artifactId>
<version>0.0.1.BUILD-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>@java.version@</maven.compiler.source>
<maven.compiler.target>@java.version@</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>@project.groupId@</groupId>
<artifactId>@project.artifactId@</artifactId>
<version>@project.version@</version>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>src/main/additional-jar/resources-1.0.0.jar</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

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

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot.maven.it</groupId>
<artifactId>run-directories</artifactId>
<version>0.0.1.BUILD-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>@java.version@</maven.compiler.source>
<maven.compiler.target>@java.version@</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>@project.groupId@</groupId>
<artifactId>@project.artifactId@</artifactId>
<version>@project.version@</version>
<configuration>
<directories>
<directory>src/main/additional-elements/</directory>
</directories>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

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

View File

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