Browse Source

Support exclusion of optional dependencies in uber-jars

Update Maven plugin with `<includeOptional>` configuration property that
can be used to toggle if optional dependencies are packages.

For back-compatibility, in 3.5.x the default is `true`.

Fixes gh-25403
pull/47427/head
Phillip Webb 3 months ago
parent
commit
f3b44031a6
  1. 36
      spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/JarIntegrationTests.java
  2. 47
      spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-optional-default/pom.xml
  3. 24
      spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-optional-default/src/main/java/org/test/SampleApplication.java
  4. 50
      spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-optional-exclude/pom.xml
  5. 24
      spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-optional-exclude/src/main/java/org/test/SampleApplication.java
  6. 50
      spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-optional-include/pom.xml
  7. 24
      spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-optional-include/src/main/java/org/test/SampleApplication.java
  8. 10
      spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java
  9. 20
      spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/DependencyFilter.java
  10. 50
      spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/DependencyFilterTests.java

36
spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/JarIntegrationTests.java

@ -202,6 +202,42 @@ class JarIntegrationTests extends AbstractArchiveIntegrationTests { @@ -202,6 +202,42 @@ class JarIntegrationTests extends AbstractArchiveIntegrationTests {
});
}
@TestTemplate
void whenAnEntryIsOptionalByDefaultAppearsInTheRepackagedJar(MavenBuild mavenBuild) {
mavenBuild.project("jar-optional-default").goals("install").execute((project) -> {
File repackaged = new File(project, "target/jar-optional-default-0.0.1.BUILD-SNAPSHOT.jar");
assertThat(jar(repackaged)).hasEntryWithNameStartingWith("BOOT-INF/classes/")
.hasEntryWithNameStartingWith("BOOT-INF/lib/spring-context")
.hasEntryWithNameStartingWith("BOOT-INF/lib/spring-core")
.hasEntryWithNameStartingWith("BOOT-INF/lib/spring-jcl")
.hasEntryWithNameStartingWith("BOOT-INF/lib/log4j-api-");
});
}
@TestTemplate
void whenAnEntryIsOptionalAndOptionalsIncludedAppearsInTheRepackagedJar(MavenBuild mavenBuild) {
mavenBuild.project("jar-optional-include").goals("install").execute((project) -> {
File repackaged = new File(project, "target/jar-optional-include-0.0.1.BUILD-SNAPSHOT.jar");
assertThat(jar(repackaged)).hasEntryWithNameStartingWith("BOOT-INF/classes/")
.hasEntryWithNameStartingWith("BOOT-INF/lib/spring-context")
.hasEntryWithNameStartingWith("BOOT-INF/lib/spring-core")
.hasEntryWithNameStartingWith("BOOT-INF/lib/spring-jcl")
.hasEntryWithNameStartingWith("BOOT-INF/lib/log4j-api-");
});
}
@TestTemplate
void whenAnEntryIsOptionalAndOptionalsExcludedDoesNotAppearInTheRepackagedJar(MavenBuild mavenBuild) {
mavenBuild.project("jar-optional-exclude").goals("install").execute((project) -> {
File repackaged = new File(project, "target/jar-optional-exclude-0.0.1.BUILD-SNAPSHOT.jar");
assertThat(jar(repackaged)).hasEntryWithNameStartingWith("BOOT-INF/classes/")
.hasEntryWithNameStartingWith("BOOT-INF/lib/spring-context")
.hasEntryWithNameStartingWith("BOOT-INF/lib/spring-core")
.hasEntryWithNameStartingWith("BOOT-INF/lib/spring-jcl")
.doesNotHaveEntryWithNameStartingWith("BOOT-INF/lib/log4j-api-");
});
}
@TestTemplate
void whenAnEntryIsExcludedWithPropertyItDoesNotAppearInTheRepackagedJar(MavenBuild mavenBuild) {
mavenBuild.project("jar")

47
spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-optional-default/pom.xml

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
<?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>jar-optional-default</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>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>@maven-jar-plugin.version@</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>@spring-framework.version@</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>@log4j2.version@</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>

24
spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-optional-default/src/main/java/org/test/SampleApplication.java

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
/*
* Copyright 2012-present 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) {
}
}

50
spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-optional-exclude/pom.xml

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
<?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>jar-optional-exclude</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>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<includeOptional>false</includeOptional>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>@maven-jar-plugin.version@</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>@spring-framework.version@</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>@log4j2.version@</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>

24
spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-optional-exclude/src/main/java/org/test/SampleApplication.java

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
/*
* Copyright 2012-present 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) {
}
}

50
spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-optional-include/pom.xml

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
<?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>jar-optional-include</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>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<includeOptional>true</includeOptional>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>@maven-jar-plugin.version@</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>@spring-framework.version@</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>@log4j2.version@</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>

24
spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-optional-include/src/main/java/org/test/SampleApplication.java

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
/*
* Copyright 2012-present 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) {
}
}

10
spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java

@ -111,6 +111,13 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo @@ -111,6 +111,13 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo
@Parameter(defaultValue = "false")
public boolean includeSystemScope;
/**
* Include optional dependencies.
* @since 3.5.7
*/
@Parameter(defaultValue = "true")
public boolean includeOptional = true;
/**
* Include JAR tools.
* @since 3.3.0
@ -228,6 +235,9 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo @@ -228,6 +235,9 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo
if (!this.includeSystemScope) {
filters.add(new ScopeFilter(null, Artifact.SCOPE_SYSTEM));
}
if (!this.includeOptional) {
filters.add(DependencyFilter.exclude(Artifact::isOptional));
}
return filters.toArray(new ArtifactsFilter[0]);
}

20
spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/DependencyFilter.java

@ -16,9 +16,11 @@ @@ -16,9 +16,11 @@
package org.springframework.boot.maven;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.shared.artifact.filter.collection.AbstractArtifactsFilter;
@ -81,4 +83,22 @@ public abstract class DependencyFilter extends AbstractArtifactsFilter { @@ -81,4 +83,22 @@ public abstract class DependencyFilter extends AbstractArtifactsFilter {
return this.filters;
}
/**
* Return a new {@link DependencyFilter} the excludes artifacts based on the given
* predicate.
* @param filter the predicate used to filter the artifacts.
* @return a new {@link DependencyFilter} instance
* @since 3.5.7
*/
public static DependencyFilter exclude(Predicate<Artifact> filter) {
return new DependencyFilter(Collections.emptyList()) {
@Override
protected boolean filter(Artifact artifact) {
return filter.test(artifact);
}
};
}
}

50
spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/DependencyFilterTests.java

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
/*
* Copyright 2012-present 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.springframework.boot.maven;
import java.util.Set;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DependencyFilter}.
*
* @author Phillip Webb
*/
class DependencyFilterTests {
@Test
void excludeFiltersBasedOnPredicate() throws ArtifactFilterException {
DependencyFilter filter = DependencyFilter.exclude(Artifact::isOptional);
ArtifactHandler ah = new DefaultArtifactHandler();
VersionRange v = VersionRange.createFromVersion("1.0.0");
DefaultArtifact a1 = new DefaultArtifact("com.example", "a1", v, "compile", "jar", null, ah, false);
DefaultArtifact a2 = new DefaultArtifact("com.example", "a2", v, "compile", "jar", null, ah, true);
DefaultArtifact a3 = new DefaultArtifact("com.example", "a3", v, "compile", "jar", null, ah, false);
Set<Artifact> filtered = filter.filter(Set.of(a1, a2, a3));
assertThat(filtered).containsExactlyInAnyOrder(a1, a3);
}
}
Loading…
Cancel
Save