Put project deps in app layer and make customization easier
Previously, when building a layered jar with Gradle, project dependencies were treated the same as any other dependency, being included in the dependencies or snapshot dependencies layer based on their version. This commit updates the default layering when using Gradle to include project dependencies in the application layer by default. The DSL has also been updated to allow their layer to be customized using new includeProjectDependencies() and excludeProjectDependencies() methods rather than relying on including and excluding them via a group:artifact:version pattern. Closes gh-23431
This commit is contained in:
@@ -140,6 +140,50 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests {
|
||||
assertExtractedLayers(layerNames, indexedLayers);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void multiModuleImplicitLayers() throws IOException {
|
||||
writeSettingsGradle();
|
||||
writeMainClass();
|
||||
writeResource();
|
||||
assertThat(this.gradleBuild.build("bootJar").task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
Map<String, List<String>> indexedLayers;
|
||||
String layerToolsJar = "BOOT-INF/lib/" + JarModeLibrary.LAYER_TOOLS.getName();
|
||||
try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) {
|
||||
assertThat(jarFile.getEntry(layerToolsJar)).isNotNull();
|
||||
assertThat(jarFile.getEntry("BOOT-INF/lib/alpha-1.2.3.jar")).isNotNull();
|
||||
assertThat(jarFile.getEntry("BOOT-INF/lib/bravo-1.2.3.jar")).isNotNull();
|
||||
assertThat(jarFile.getEntry("BOOT-INF/lib/commons-lang3-3.9.jar")).isNotNull();
|
||||
assertThat(jarFile.getEntry("BOOT-INF/lib/spring-core-5.2.5.RELEASE.jar")).isNotNull();
|
||||
assertThat(jarFile.getEntry("BOOT-INF/lib/spring-jcl-5.2.5.RELEASE.jar")).isNotNull();
|
||||
assertThat(jarFile.getEntry("BOOT-INF/lib/library-1.0-SNAPSHOT.jar")).isNotNull();
|
||||
assertThat(jarFile.getEntry("BOOT-INF/classes/example/Main.class")).isNotNull();
|
||||
assertThat(jarFile.getEntry("BOOT-INF/classes/static/file.txt")).isNotNull();
|
||||
indexedLayers = readLayerIndex(jarFile);
|
||||
}
|
||||
List<String> layerNames = Arrays.asList("dependencies", "spring-boot-loader", "snapshot-dependencies",
|
||||
"application");
|
||||
assertThat(indexedLayers.keySet()).containsExactlyElementsOf(layerNames);
|
||||
Set<String> expectedDependencies = new TreeSet<>();
|
||||
expectedDependencies.add("BOOT-INF/lib/commons-lang3-3.9.jar");
|
||||
expectedDependencies.add("BOOT-INF/lib/spring-core-5.2.5.RELEASE.jar");
|
||||
expectedDependencies.add("BOOT-INF/lib/spring-jcl-5.2.5.RELEASE.jar");
|
||||
Set<String> expectedSnapshotDependencies = new TreeSet<>();
|
||||
expectedSnapshotDependencies.add("BOOT-INF/lib/library-1.0-SNAPSHOT.jar");
|
||||
(layerToolsJar.contains("SNAPSHOT") ? expectedSnapshotDependencies : expectedDependencies).add(layerToolsJar);
|
||||
assertThat(indexedLayers.get("dependencies")).containsExactlyElementsOf(expectedDependencies);
|
||||
assertThat(indexedLayers.get("spring-boot-loader")).containsExactly("org/");
|
||||
assertThat(indexedLayers.get("snapshot-dependencies")).containsExactlyElementsOf(expectedSnapshotDependencies);
|
||||
assertThat(indexedLayers.get("application")).containsExactly("BOOT-INF/classes/", "BOOT-INF/classpath.idx",
|
||||
"BOOT-INF/layers.idx", "BOOT-INF/lib/alpha-1.2.3.jar", "BOOT-INF/lib/bravo-1.2.3.jar", "META-INF/");
|
||||
BuildResult listLayers = this.gradleBuild.build("listLayers");
|
||||
assertThat(listLayers.task(":listLayers").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
String listLayersOutput = listLayers.getOutput();
|
||||
assertThat(new BufferedReader(new StringReader(listLayersOutput)).lines()).containsSequence(layerNames);
|
||||
BuildResult extractLayers = this.gradleBuild.build("extractLayers");
|
||||
assertThat(extractLayers.task(":extractLayers").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertExtractedLayers(layerNames, indexedLayers);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void customLayers() throws IOException {
|
||||
writeMainClass();
|
||||
|
||||
@@ -29,8 +29,11 @@ import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.DomainObjectSet;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.DependencySet;
|
||||
import org.gradle.api.artifacts.ModuleVersionIdentifier;
|
||||
import org.gradle.api.artifacts.ProjectDependency;
|
||||
import org.gradle.api.artifacts.ResolvableDependencies;
|
||||
import org.gradle.api.artifacts.ResolvedArtifact;
|
||||
import org.gradle.api.artifacts.ResolvedConfiguration;
|
||||
@@ -41,6 +44,7 @@ import org.gradle.api.artifacts.component.ProjectComponentIdentifier;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.loader.tools.JarModeLibrary;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -56,6 +60,7 @@ import static org.mockito.Mockito.mock;
|
||||
* @author Scott Frederick
|
||||
* @author Paddy Drury
|
||||
*/
|
||||
@ClassPathExclusions("kotlin-daemon-client-*")
|
||||
class BootJarTests extends AbstractBootArchiveTests<BootJar> {
|
||||
|
||||
BootJarTests() {
|
||||
@@ -307,6 +312,10 @@ class BootJarTests extends AbstractBootArchiveTests<BootJar> {
|
||||
given(configuration.getResolvedConfiguration()).willReturn(resolvedConfiguration);
|
||||
ResolvableDependencies resolvableDependencies = mock(ResolvableDependencies.class);
|
||||
given(configuration.getIncoming()).willReturn(resolvableDependencies);
|
||||
DependencySet dependencies = mock(DependencySet.class);
|
||||
DomainObjectSet<ProjectDependency> projectDependencies = mock(DomainObjectSet.class);
|
||||
given(dependencies.withType(ProjectDependency.class)).willReturn(projectDependencies);
|
||||
given(configuration.getAllDependencies()).willReturn(dependencies);
|
||||
willAnswer((invocation) -> {
|
||||
invocation.getArgument(0, Action.class).execute(resolvableDependencies);
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user