From 98644df64dd4e2c0b72a5353418b31e083b63cd9 Mon Sep 17 00:00:00 2001 From: Paddy Drury Date: Tue, 28 Apr 2020 10:25:25 +0100 Subject: [PATCH] Stop limiting layer customization to external modules See gh-21207 --- .../gradle/tasks/bundling/LayerResolver.java | 32 ++++--- .../bundling/BootJarIntegrationTests.java | 69 +++++++++++++++ .../gradle/tasks/bundling/BootJarTests.java | 86 +++++++++++++------ ...endenciesCanBeIncludedInCustomLayer.gradle | 60 +++++++++++++ 4 files changed, 209 insertions(+), 38 deletions(-) create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests-projectDependenciesCanBeIncludedInCustomLayer.gradle diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LayerResolver.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LayerResolver.java index 82213fc902f..30ee9b59805 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LayerResolver.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LayerResolver.java @@ -24,11 +24,13 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; -import org.gradle.api.artifacts.ArtifactCollection; import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.ModuleVersionIdentifier; +import org.gradle.api.artifacts.ResolvedArtifact; +import org.gradle.api.artifacts.ResolvedConfiguration; import org.gradle.api.artifacts.component.ComponentIdentifier; import org.gradle.api.artifacts.component.ModuleComponentIdentifier; -import org.gradle.api.artifacts.result.ResolvedArtifactResult; +import org.gradle.api.artifacts.component.ProjectComponentIdentifier; import org.gradle.api.file.FileCopyDetails; import org.gradle.api.specs.Spec; @@ -43,6 +45,7 @@ import org.springframework.boot.loader.tools.LibraryCoordinates; * @author Madhura Bhave * @author Scott Frederick * @author Phillip Webb + * @author Paddy Drury * @see BootZipCopyAction */ class LayerResolver { @@ -110,7 +113,7 @@ class LayerResolver { if (configuration.isCanBeResolved() && !DEPRECATED_FOR_RESOLUTION_CONFIGURATIONS.contains(configuration.getName())) { this.configurationDependencies.put(configuration, - new ResolvedConfigurationDependencies(configuration.getIncoming().getArtifacts())); + new ResolvedConfigurationDependencies(configuration.getResolvedConfiguration())); } } @@ -133,14 +136,15 @@ class LayerResolver { private final Map artifactCoordinates = new LinkedHashMap<>(); - ResolvedConfigurationDependencies(ArtifactCollection resolvedDependencies) { - if (resolvedDependencies != null) { - for (ResolvedArtifactResult resolvedArtifact : resolvedDependencies.getArtifacts()) { + ResolvedConfigurationDependencies(ResolvedConfiguration resolvedConfiguration) { + if (resolvedConfiguration != null) { + for (ResolvedArtifact resolvedArtifact : resolvedConfiguration.getResolvedArtifacts()) { ComponentIdentifier identifier = resolvedArtifact.getId().getComponentIdentifier(); - if (identifier instanceof ModuleComponentIdentifier) { + if (identifier instanceof ModuleComponentIdentifier + || identifier instanceof ProjectComponentIdentifier) { this.artifactCoordinates.put(resolvedArtifact.getFile(), - new ModuleComponentIdentifierLibraryCoordinates( - (ModuleComponentIdentifier) identifier)); + new ModuleVersionIdentifierLibraryCoordinates( + resolvedArtifact.getModuleVersion().getId())); } } } @@ -153,13 +157,13 @@ class LayerResolver { } /** - * Adapts a {@link ModuleComponentIdentifier} to {@link LibraryCoordinates}. + * Adapts a {@link ModuleVersionIdentifier} to {@link LibraryCoordinates}. */ - private static class ModuleComponentIdentifierLibraryCoordinates implements LibraryCoordinates { + private static class ModuleVersionIdentifierLibraryCoordinates implements LibraryCoordinates { - private final ModuleComponentIdentifier identifier; + private final ModuleVersionIdentifier identifier; - ModuleComponentIdentifierLibraryCoordinates(ModuleComponentIdentifier identifier) { + ModuleVersionIdentifierLibraryCoordinates(ModuleVersionIdentifier identifier) { this.identifier = identifier; } @@ -170,7 +174,7 @@ class LayerResolver { @Override public String getArtifactId() { - return this.identifier.getModule(); + return this.identifier.getName(); } @Override diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java index 63dd2a970a0..5b584f1bc05 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java @@ -53,6 +53,7 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Andy Wilkinson * @author Madhura Bhave + * @author Paddy Drury */ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { @@ -176,6 +177,64 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { assertExtractedLayers(layerNames, indexedLayers); } + @TestTemplate + void projectDependenciesCanBeIncludedInCustomLayer() throws IOException { + writeSettingsGradle(); + writeMainClass(); + writeResource(); + BuildResult build = this.gradleBuild.build("bootJar"); + assertThat(build.task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + Map> 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/foo-1.2.3.jar")).isNotNull(); + assertThat(jarFile.getEntry("BOOT-INF/lib/bar-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/commons-io-2.7-SNAPSHOT.jar")).isNotNull(); + assertThat(jarFile.getEntry("BOOT-INF/classes/example/Main.class")).isNotNull(); + assertThat(jarFile.getEntry("BOOT-INF/classes/static/file.txt")).isNotNull(); + assertThat(jarFile.getEntry("BOOT-INF/layers.idx")).isNotNull(); + indexedLayers = readLayerIndex(jarFile); + } + List layerNames = Arrays.asList("dependencies", "commons-dependencies", "snapshot-dependencies", + "subproject-dependencies", "static", "app"); + assertThat(indexedLayers.keySet()).containsExactlyElementsOf(layerNames); + Set expectedSubprojectDependencies = new TreeSet<>(); + expectedSubprojectDependencies.add("BOOT-INF/lib/foo-1.2.3.jar"); + expectedSubprojectDependencies.add("BOOT-INF/lib/bar-1.2.3.jar"); + Set expectedDependencies = new TreeSet<>(); + expectedDependencies.add("BOOT-INF/lib/spring-core-5.2.5.RELEASE.jar"); + expectedDependencies.add("BOOT-INF/lib/spring-jcl-5.2.5.RELEASE.jar"); + List expectedSnapshotDependencies = new ArrayList<>(); + expectedSnapshotDependencies.add("BOOT-INF/lib/commons-io-2.7-SNAPSHOT.jar"); + (layerToolsJar.contains("SNAPSHOT") ? expectedSnapshotDependencies : expectedDependencies).add(layerToolsJar); + assertThat(indexedLayers.get("subproject-dependencies")) + .containsExactlyElementsOf(expectedSubprojectDependencies); + assertThat(indexedLayers.get("dependencies")).containsExactlyElementsOf(expectedDependencies); + assertThat(indexedLayers.get("commons-dependencies")).containsExactly("BOOT-INF/lib/commons-lang3-3.9.jar"); + assertThat(indexedLayers.get("snapshot-dependencies")).containsExactlyElementsOf(expectedSnapshotDependencies); + assertThat(indexedLayers.get("static")).containsExactly("BOOT-INF/classes/static/"); + List appLayer = new ArrayList<>(indexedLayers.get("app")); + Set nonLoaderEntries = new TreeSet<>(); + nonLoaderEntries.add("BOOT-INF/classes/example/"); + nonLoaderEntries.add("BOOT-INF/classpath.idx"); + nonLoaderEntries.add("BOOT-INF/layers.idx"); + nonLoaderEntries.add("META-INF/"); + assertThat(appLayer).containsSubsequence(nonLoaderEntries); + appLayer.removeAll(nonLoaderEntries); + assertThat(appLayer).containsExactly("org/"); + 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); + } + private void assertExtractedLayers(List layerNames, Map> indexedLayers) throws IOException { Map> extractedLayers = readExtractedLayers(this.gradleBuild.getProjectDir(), layerNames); @@ -201,6 +260,16 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { return false; } + private void writeSettingsGradle() { + File settings = new File(this.gradleBuild.getProjectDir(), "settings.gradle"); + try (PrintWriter writer = new PrintWriter(new FileWriter(settings))) { + writer.println("include 'foo', 'bar'"); + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + private void writeMainClass() { File examplePackage = new File(this.gradleBuild.getProjectDir(), "src/main/java/example"); examplePackage.mkdirs(); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarTests.java index fc42799e542..8ff1107d086 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarTests.java @@ -30,12 +30,14 @@ import java.util.stream.Collectors; import java.util.zip.ZipEntry; import org.gradle.api.Action; -import org.gradle.api.artifacts.ArtifactCollection; import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.ResolvableDependencies; +import org.gradle.api.artifacts.ModuleVersionIdentifier; +import org.gradle.api.artifacts.ResolvedArtifact; +import org.gradle.api.artifacts.ResolvedConfiguration; +import org.gradle.api.artifacts.ResolvedModuleVersion; import org.gradle.api.artifacts.component.ComponentArtifactIdentifier; import org.gradle.api.artifacts.component.ModuleComponentIdentifier; -import org.gradle.api.artifacts.result.ResolvedArtifactResult; +import org.gradle.api.artifacts.component.ProjectComponentIdentifier; import org.junit.jupiter.api.Test; import org.springframework.boot.gradle.tasks.bundling.BootJarTests.TestBootJar; @@ -51,6 +53,7 @@ import static org.mockito.Mockito.mock; * @author Andy Wilkinson * @author Madhura Bhave * @author Scott Frederick + * @author Paddy Drury */ class BootJarTests extends AbstractBootArchiveTests { @@ -99,8 +102,10 @@ class BootJarTests extends AbstractBootArchiveTests { try (JarFile jarFile = new JarFile(createLayeredJar())) { List entryNames = getEntryNames(jarFile); assertThat(entryNames).contains("BOOT-INF/lib/first-library.jar", "BOOT-INF/lib/second-library.jar", - "BOOT-INF/lib/third-library-SNAPSHOT.jar", "BOOT-INF/classes/com/example/Application.class", - "BOOT-INF/classes/application.properties", "BOOT-INF/classes/static/test.css"); + "BOOT-INF/lib/third-library-SNAPSHOT.jar", "BOOT-INF/lib/first-project-library.jar", + "BOOT-INF/lib/second-project-library-SNAPSHOT.jar", + "BOOT-INF/classes/com/example/Application.class", "BOOT-INF/classes/application.properties", + "BOOT-INF/classes/static/test.css"); List index = entryLines(jarFile, "BOOT-INF/layers.idx"); assertThat(getLayerNames(index)).containsExactly("dependencies", "spring-boot-loader", "snapshot-dependencies", "application"); @@ -108,6 +113,7 @@ class BootJarTests extends AbstractBootArchiveTests { List expected = new ArrayList<>(); expected.add("- \"dependencies\":"); expected.add(" - \"BOOT-INF/lib/first-library.jar\""); + expected.add(" - \"BOOT-INF/lib/first-project-library.jar\""); expected.add(" - \"BOOT-INF/lib/second-library.jar\""); if (!layerToolsJar.contains("SNAPSHOT")) { expected.add(" - \"" + layerToolsJar + "\""); @@ -115,6 +121,7 @@ class BootJarTests extends AbstractBootArchiveTests { expected.add("- \"spring-boot-loader\":"); expected.add(" - \"org/\""); expected.add("- \"snapshot-dependencies\":"); + expected.add(" - \"BOOT-INF/lib/second-project-library-SNAPSHOT.jar\""); if (layerToolsJar.contains("SNAPSHOT")) { expected.add(" - \"" + layerToolsJar + "\""); } @@ -145,8 +152,10 @@ class BootJarTests extends AbstractBootArchiveTests { try (JarFile jarFile = new JarFile(jar)) { List entryNames = getEntryNames(jar); assertThat(entryNames).contains("BOOT-INF/lib/first-library.jar", "BOOT-INF/lib/second-library.jar", - "BOOT-INF/lib/third-library-SNAPSHOT.jar", "BOOT-INF/classes/com/example/Application.class", - "BOOT-INF/classes/application.properties", "BOOT-INF/classes/static/test.css"); + "BOOT-INF/lib/third-library-SNAPSHOT.jar", "BOOT-INF/lib/first-project-library.jar", + "BOOT-INF/lib/second-project-library-SNAPSHOT.jar", + "BOOT-INF/classes/com/example/Application.class", "BOOT-INF/classes/application.properties", + "BOOT-INF/classes/static/test.css"); List index = entryLines(jarFile, "BOOT-INF/layers.idx"); assertThat(getLayerNames(index)).containsExactly("my-deps", "my-internal-deps", "my-snapshot-deps", "resources", "application"); @@ -156,8 +165,10 @@ class BootJarTests extends AbstractBootArchiveTests { expected.add(" - \"" + layerToolsJar + "\""); expected.add("- \"my-internal-deps\":"); expected.add(" - \"BOOT-INF/lib/first-library.jar\""); + expected.add(" - \"BOOT-INF/lib/first-project-library.jar\""); expected.add(" - \"BOOT-INF/lib/second-library.jar\""); expected.add("- \"my-snapshot-deps\":"); + expected.add(" - \"BOOT-INF/lib/second-project-library-SNAPSHOT.jar\""); expected.add(" - \"BOOT-INF/lib/third-library-SNAPSHOT.jar\""); expected.add("- \"resources\":"); expected.add(" - \"BOOT-INF/classes/static/\""); @@ -179,6 +190,10 @@ class BootJarTests extends AbstractBootArchiveTests { assertThat(jarFile.getEntry("BOOT-INF/lib/second-library.jar").getMethod()).isEqualTo(ZipEntry.STORED); assertThat(jarFile.getEntry("BOOT-INF/lib/third-library-SNAPSHOT.jar").getMethod()) .isEqualTo(ZipEntry.STORED); + assertThat(jarFile.getEntry("BOOT-INF/lib/first-project-library.jar").getMethod()) + .isEqualTo(ZipEntry.STORED); + assertThat(jarFile.getEntry("BOOT-INF/lib/second-project-library-SNAPSHOT.jar").getMethod()) + .isEqualTo(ZipEntry.STORED); } } @@ -186,7 +201,8 @@ class BootJarTests extends AbstractBootArchiveTests { void whenJarIsLayeredClasspathIndexPointsToLayeredLibs() throws IOException { try (JarFile jarFile = new JarFile(createLayeredJar())) { assertThat(entryLines(jarFile, "BOOT-INF/classpath.idx")).containsExactly("- \"first-library.jar\"", - "- \"second-library.jar\"", "- \"third-library-SNAPSHOT.jar\""); + "- \"second-library.jar\"", "- \"third-library-SNAPSHOT.jar\"", "- \"first-project-library.jar\"", + "- \"second-project-library-SNAPSHOT.jar\""); } } @@ -209,7 +225,8 @@ class BootJarTests extends AbstractBootArchiveTests { assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classpath-Index")) .isEqualTo("BOOT-INF/classpath.idx"); assertThat(entryLines(jarFile, "BOOT-INF/classpath.idx")).containsExactly("- \"first-library.jar\"", - "- \"second-library.jar\"", "- \"third-library-SNAPSHOT.jar\""); + "- \"second-library.jar\"", "- \"third-library-SNAPSHOT.jar\"", "- \"first-project-library.jar\"", + "- \"second-project-library-SNAPSHOT.jar\""); } } @@ -251,34 +268,55 @@ class BootJarTests extends AbstractBootArchiveTests { File css = new File(staticResources, "test.css"); css.createNewFile(); bootJar.classpath(classesJavaMain, resourcesMain, jarFile("first-library.jar"), jarFile("second-library.jar"), - jarFile("third-library-SNAPSHOT.jar")); - Set artifacts = new LinkedHashSet<>(); + jarFile("third-library-SNAPSHOT.jar"), jarFile("first-project-library.jar"), + jarFile("second-project-library-SNAPSHOT.jar")); + Set artifacts = new LinkedHashSet<>(); artifacts.add(mockLibraryArtifact("first-library.jar", "com.example", "first-library", "1.0.0")); artifacts.add(mockLibraryArtifact("second-library.jar", "com.example", "second-library", "1.0.0")); artifacts.add( mockLibraryArtifact("third-library-SNAPSHOT.jar", "com.example", "third-library", "1.0.0.SNAPSHOT")); - ArtifactCollection resolvedDependencies = mock(ArtifactCollection.class); - given(resolvedDependencies.getArtifacts()).willReturn(artifacts); - ResolvableDependencies resolvableDependencies = mock(ResolvableDependencies.class); - given(resolvableDependencies.getArtifacts()).willReturn(resolvedDependencies); + artifacts + .add(mockProjectArtifact("first-project-library.jar", "com.example", "first-project-library", "1.0.0")); + artifacts.add(mockProjectArtifact("second-project-library-SNAPSHOT.jar", "com.example", + "second-project-library", "1.0.0.SNAPSHOT")); + ResolvedConfiguration resolvedConfiguration = mock(ResolvedConfiguration.class); + given(resolvedConfiguration.getResolvedArtifacts()).willReturn(artifacts); Configuration configuration = mock(Configuration.class); given(configuration.isCanBeResolved()).willReturn(true); - given(configuration.getIncoming()).willReturn(resolvableDependencies); + given(configuration.getResolvedConfiguration()).willReturn(resolvedConfiguration); bootJar.setConfiguration(Collections.singleton(configuration)); } - private ResolvedArtifactResult mockLibraryArtifact(String fileName, String group, String module, String version) { - ModuleComponentIdentifier identifier = mock(ModuleComponentIdentifier.class); - given(identifier.getGroup()).willReturn(group); - given(identifier.getModule()).willReturn(module); - given(identifier.getVersion()).willReturn(version); + private ResolvedArtifact mockLibraryArtifact(String fileName, String group, String module, String version) { + ModuleComponentIdentifier moduleComponentIdentifier = mock(ModuleComponentIdentifier.class); ComponentArtifactIdentifier libraryArtifactId = mock(ComponentArtifactIdentifier.class); - given(libraryArtifactId.getComponentIdentifier()).willReturn(identifier); - ResolvedArtifactResult libraryArtifact = mock(ResolvedArtifactResult.class); + given(libraryArtifactId.getComponentIdentifier()).willReturn(moduleComponentIdentifier); + ResolvedArtifact libraryArtifact = mockArtifact(fileName, group, module, version); + given(libraryArtifact.getId()).willReturn(libraryArtifactId); + return libraryArtifact; + } + + private ResolvedArtifact mockProjectArtifact(String fileName, String group, String module, String version) { + ProjectComponentIdentifier projectComponentIdentifier = mock(ProjectComponentIdentifier.class); + ComponentArtifactIdentifier projectArtifactId = mock(ComponentArtifactIdentifier.class); + given(projectArtifactId.getComponentIdentifier()).willReturn(projectComponentIdentifier); + ResolvedArtifact projectArtifact = mockArtifact(fileName, group, module, version); + given(projectArtifact.getId()).willReturn(projectArtifactId); + return projectArtifact; + } + + private ResolvedArtifact mockArtifact(String fileName, String group, String module, String version) { + ModuleVersionIdentifier moduleVersionIdentifier = mock(ModuleVersionIdentifier.class); + given(moduleVersionIdentifier.getGroup()).willReturn(group); + given(moduleVersionIdentifier.getName()).willReturn(module); + given(moduleVersionIdentifier.getVersion()).willReturn(version); + ResolvedModuleVersion moduleVersion = mock(ResolvedModuleVersion.class); + given(moduleVersion.getId()).willReturn(moduleVersionIdentifier); + ResolvedArtifact libraryArtifact = mock(ResolvedArtifact.class); File file = new File(this.temp, fileName).getAbsoluteFile(); System.out.println(file); given(libraryArtifact.getFile()).willReturn(file); - given(libraryArtifact.getId()).willReturn(libraryArtifactId); + given(libraryArtifact.getModuleVersion()).willReturn(moduleVersion); return libraryArtifact; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests-projectDependenciesCanBeIncludedInCustomLayer.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests-projectDependenciesCanBeIncludedInCustomLayer.gradle new file mode 100644 index 00000000000..3bc3cbcf1f8 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests-projectDependenciesCanBeIncludedInCustomLayer.gradle @@ -0,0 +1,60 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '{version}' +} + +subprojects { + apply plugin: 'java' + group = 'org.example.projects' + version = '1.2.3' +} + +bootJar { + mainClassName = 'com.example.Application' + layered { + application { + intoLayer("static") { + include "META-INF/resources/**", "resources/**", "static/**", "public/**" + } + intoLayer("app") + } + dependencies { + intoLayer("subproject-dependencies") { + include "org.example.projects:*" + } + intoLayer("snapshot-dependencies") { + include "*:*:*SNAPSHOT" + } + intoLayer("commons-dependencies") { + include "org.apache.commons:*" + } + intoLayer("dependencies") + } + layerOrder = ["dependencies", "commons-dependencies", "snapshot-dependencies", "subproject-dependencies", "static", "app"] + } +} + +repositories { + mavenCentral() + maven { url "https://repository.apache.org/content/repositories/snapshots" } +} + +dependencies { + implementation(project(':foo')) + implementation(project(':bar')) + implementation("commons-io:commons-io:2.7-SNAPSHOT") + implementation("org.apache.commons:commons-lang3:3.9") + implementation("org.springframework:spring-core:5.2.5.RELEASE") +} + +task listLayers(type: JavaExec) { + classpath = bootJar.outputs.files + systemProperties = [ "jarmode": "layertools" ] + args "list" +} + +task extractLayers(type: JavaExec) { + classpath = bootJar.outputs.files + systemProperties = [ "jarmode": "layertools" ] + args "extract" +}