diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/JarIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/JarIntegrationTests.java index 72bc73f0bb61..31f6b520a52d 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/JarIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/JarIntegrationTests.java @@ -194,6 +194,33 @@ void whenAnEntryIsExcludedWithPropertyItDoesNotAppearInTheRepackagedJar(MavenBui }); } + @TestTemplate + void whenAnEntryIsIncludedOnlyIncludedEntriesAppearInTheRepackagedJar(MavenBuild mavenBuild) { + mavenBuild.project("jar-include-entry").goals("install").execute((project) -> { + File repackaged = new File(project, "target/jar-include-entry-0.0.1.BUILD-SNAPSHOT.jar"); + assertThat(jar(repackaged)).hasEntryWithNameStartingWith("BOOT-INF/classes/") + .hasEntryWithNameStartingWith("BOOT-INF/lib/jakarta.servlet-api-") + .doesNotHaveEntryWithNameStartingWith("BOOT-INF/lib/spring-context") + .doesNotHaveEntryWithNameStartingWith("BOOT-INF/lib/spring-core") + .doesNotHaveEntryWithNameStartingWith("BOOT-INF/lib/spring-jcl"); + }); + } + + @TestTemplate + void whenAnIncludeIsSpecifiedAsAPropertyOnlyIncludedEntriesAppearInTheRepackagedJar(MavenBuild mavenBuild) { + mavenBuild.project("jar") + .systemProperty("spring-boot.includes", "jakarta.servlet:jakarta.servlet-api") + .goals("install") + .execute((project) -> { + File repackaged = new File(project, "target/jar-0.0.1.BUILD-SNAPSHOT.jar"); + assertThat(jar(repackaged)).hasEntryWithNameStartingWith("BOOT-INF/classes/") + .hasEntryWithNameStartingWith("BOOT-INF/lib/jakarta.servlet-api-") + .doesNotHaveEntryWithNameStartingWith("BOOT-INF/lib/spring-context") + .doesNotHaveEntryWithNameStartingWith("BOOT-INF/lib/spring-core") + .doesNotHaveEntryWithNameStartingWith("BOOT-INF/lib/spring-jcl"); + }); + } + @TestTemplate void whenAGroupIsExcludedNoEntriesInThatGroupAppearInTheRepackagedJar(MavenBuild mavenBuild) { mavenBuild.project("jar-exclude-group").goals("install").execute((project) -> { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-include-entry/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-include-entry/pom.xml new file mode 100644 index 000000000000..9e4a5c10dfda --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-include-entry/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + org.springframework.boot.maven.it + jar-include-entry + 0.0.1.BUILD-SNAPSHOT + + UTF-8 + @java.version@ + @java.version@ + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + repackage + + + + + jakarta.servlet + jakarta.servlet-api + + + + + + + + + + + org.springframework + spring-context + @spring-framework.version@ + + + jakarta.servlet + jakarta.servlet-api + @jakarta-servlet.version@ + provided + + + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-include-entry/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-include-entry/src/main/java/org/test/SampleApplication.java new file mode 100644 index 000000000000..1277cdbc5a63 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-include-entry/src/main/java/org/test/SampleApplication.java @@ -0,0 +1,24 @@ +/* + * Copyright 2012-2024 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; + +public class SampleApplication { + + public static void main(String[] args) { + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java index 8b5409c6e7cc..63c0ff0fff32 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -71,9 +71,10 @@ public abstract class AbstractDependencyFilterMojo extends AbstractMojo { /** * Collection of artifact definitions to include. The {@link Include} element defines - * mandatory {@code groupId} and {@code artifactId} properties and an optional - * mandatory {@code groupId} and {@code artifactId} properties and an optional - * {@code classifier} property. + * mandatory {@code groupId} and {@code artifactId} components and an optional + * {@code classifier} component. When configured as a property, values should be + * comma-separated with colon-separated components: + * {@code groupId:artifactId,groupId:artifactId:classifier} * @since 1.2.0 */ @Parameter(property = "spring-boot.includes") diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Exclude.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Exclude.java index 9a795f11df52..23cf5e30deb0 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Exclude.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Exclude.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2024 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. @@ -16,8 +16,6 @@ package org.springframework.boot.maven; -import org.springframework.util.Assert; - /** * A model for a dependency to exclude. * @@ -26,17 +24,4 @@ */ public class Exclude extends FilterableDependency { - // Maven looks for this public method if giving excludes as property - // e.g. -Dspring-boot.excludes=myGroupId:myArtifactId:my-optional-classifier,foo:baz - public void set(String propertyInput) { - String[] parts = propertyInput.split(":"); - Assert.isTrue(parts.length == 2 || parts.length == 3, - "Exclude must be in the form groupId:artifactId:optional-classifier"); - setGroupId(parts[0]); - setArtifactId(parts[1]); - if (parts.length == 3) { - setClassifier(parts[2]); - } - } - } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/FilterableDependency.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/FilterableDependency.java index 2b4ead934f2a..2d12921fa055 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/FilterableDependency.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/FilterableDependency.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2024 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. @@ -18,13 +18,16 @@ import org.apache.maven.plugins.annotations.Parameter; +import org.springframework.util.Assert; + /** * A model for a dependency to include or exclude. * * @author Stephane Nicoll * @author David Turanski + * @since 3.1.11 */ -abstract class FilterableDependency { +public abstract class FilterableDependency { /** * The groupId of the artifact to exclude. @@ -68,4 +71,20 @@ void setClassifier(String classifier) { this.classifier = classifier; } + /** + * Configures the include or exclude using a user-provided property in the form + * {@code groupId:artifactId} or {@code groupId:artifactId:classifier}. + * @param property the user-provided property + */ + public void set(String property) { + String[] parts = property.split(":"); + Assert.isTrue(parts.length == 2 || parts.length == 3, getClass().getSimpleName() + + " must be in the form groupId:artifactId or groupId:artifactId:classifier"); + setGroupId(parts[0]); + setArtifactId(parts[1]); + if (parts.length == 3) { + setClassifier(parts[2]); + } + } + }