From a06f4f21e387ebdd115b03d6506194a7f57140a2 Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Mon, 23 Mar 2020 12:59:42 -0700 Subject: [PATCH] Combine application and resources layers into a single layer Closes gh-20562 --- .../src/docs/asciidoc/packaging.adoc | 7 +++---- .../packaging/boot-jar-layered-custom.gradle | 8 +------- .../boot-jar-layered-custom.gradle.kts | 8 +------- .../bundling/BootJarIntegrationTests.java | 2 +- .../gradle/tasks/bundling/BootJarTests.java | 4 ++-- .../loader/tools/ImplicitLayerResolver.java | 18 ------------------ .../boot/loader/tools/StandardLayers.java | 7 ------- .../tools/ImplicitLayerResolverTests.java | 12 ++++++------ .../src/docs/asciidoc/packaging.adoc | 16 +++------------- 9 files changed, 17 insertions(+), 65 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/packaging.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/packaging.adoc index ebd5523039..64d21d52bd 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/packaging.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/packaging.adoc @@ -284,11 +284,10 @@ By default, the following layers are created: * `dependencies` for any dependency whose version does not contain `SNAPSHOT`. * `snapshot-dependencies` for any dependency whose version contains `SNAPSHOT`. -* `resources` for static resources at the default locations, i.e. `META-INF/resources/`, `resources/`, `static/`, `public/`. -* `application` for any other classes and resources. +* `application` for application classes and resources. The layers order is important as it determines how likely previous layers can be cached when part of the application changes. -The default order is `dependencies`, `snapshot-dependencies`, `resources`, and `application`. +The default order is `dependencies`, `snapshot-dependencies`, and `application`. Content that is least likely to change should be added first, followed by layers that are more likely to change. When you create a layered jar, the `spring-boot-layertools` jar will be added as a dependency to your jar. @@ -328,7 +327,7 @@ include::../gradle/packaging/boot-jar-layered-custom.gradle.kts[tags=layered] Each `layerContent` closure defines a strategy to include or exclude an entry of the jar in a layer. When an entry matches a strategy, it is included in the layer and further strategies are ignored. -This is illustrated by the `dependencies` and `application` layers that have a "catch-all" include filter used to add any libraries or classes that were not processed by previous strategies. +This is illustrated by the `dependencies` layer that has a "catch-all" include filter used to add any libraries that were not processed by previous strategies. The content of a `libraries` layer can be customized using filters to `include` or `exclude` based on the dependency coordinates. The format is `groupId:artifactId[:version]`. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-custom.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-custom.gradle index cd0ffa6c61..11e33867bf 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-custom.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-custom.gradle @@ -10,7 +10,7 @@ bootJar { // tag::layered[] bootJar { layers { - layersOrder "dependencies", "snapshot-dependencies", "resources", "application" + layersOrder "dependencies", "snapshot-dependencies", "application" libraries { layerContent("snapshot-dependencies") { coordinates { @@ -24,12 +24,6 @@ bootJar { } } application { - layerContent("resources") { - locations { - include "META-INF/resources/**", "resources/**" - include "static/**", "public/**" - } - } layerContent("application") { locations { include "**" diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-custom.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-custom.gradle.kts index 62fd3118ae..c4a3bf7747 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-custom.gradle.kts +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-custom.gradle.kts @@ -8,7 +8,7 @@ plugins { // tag::layered[] tasks.getByName("bootJar") { layers { - layersOrder("dependencies", "snapshot-dependencies", "resources", "application") + layersOrder("dependencies", "snapshot-dependencies", "application") libraries { layerContent("snapshot-dependencies") { coordinates { @@ -22,12 +22,6 @@ tasks.getByName("bootJar") { } } application { - layerContent("resources") { - locations { - include("META-INF/resources/**", "resources/**") - include("static/**", "public/**") - } - } layerContent("application") { locations { include("**") 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 c96a1ef842..a6a63dabb7 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 @@ -81,7 +81,7 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { assertThat(jarFile.getEntry("BOOT-INF/layers/snapshot-dependencies/lib/commons-io-2.7-SNAPSHOT.jar")) .isNotNull(); assertThat(jarFile.getEntry("BOOT-INF/layers/application/classes/example/Main.class")).isNotNull(); - assertThat(jarFile.getEntry("BOOT-INF/layers/resources/classes/static/file.txt")).isNotNull(); + assertThat(jarFile.getEntry("BOOT-INF/layers/application/classes/static/file.txt")).isNotNull(); } } 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 3228909c31..0448b9af26 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 @@ -103,7 +103,7 @@ class BootJarTests extends AbstractBootArchiveTests { void whenJarIsLayeredThenLayersIndexIsPresentAndListsLayersInOrder() throws IOException { try (JarFile jarFile = new JarFile(createLayeredJar())) { assertThat(entryLines(jarFile, "BOOT-INF/layers.idx")).containsExactly("dependencies", - "snapshot-dependencies", "resources", "application"); + "snapshot-dependencies", "application"); } } @@ -116,7 +116,7 @@ class BootJarTests extends AbstractBootArchiveTests { .contains("BOOT-INF/layers/snapshot-dependencies/lib/third-library-SNAPSHOT.jar") .containsSubsequence("BOOT-INF/layers/application/classes/com/example/Application.class", "BOOT-INF/layers/application/classes/application.properties") - .contains("BOOT-INF/layers/resources/classes/static/test.css"); + .contains("BOOT-INF/layers/application/classes/static/test.css"); } @Test diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/ImplicitLayerResolver.java b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/ImplicitLayerResolver.java index a774a167b4..f585819074 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/ImplicitLayerResolver.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/ImplicitLayerResolver.java @@ -24,13 +24,8 @@ package org.springframework.boot.loader.tools; */ class ImplicitLayerResolver extends StandardLayers { - private static final String[] RESOURCE_LOCATIONS = { "META-INF/resources/", "resources/", "static/", "public/" }; - @Override public Layer getLayer(String name) { - if (!isClassFile(name) && isInResourceLocation(name)) { - return RESOURCES; - } return APPLICATION; } @@ -42,17 +37,4 @@ class ImplicitLayerResolver extends StandardLayers { return DEPENDENCIES; } - private boolean isClassFile(String name) { - return name.endsWith(".class"); - } - - private boolean isInResourceLocation(String name) { - for (String resourceLocation : RESOURCE_LOCATIONS) { - if (name.startsWith(resourceLocation)) { - return true; - } - } - return false; - } - } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/StandardLayers.java b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/StandardLayers.java index e4b0f4a91d..e7b0712f05 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/StandardLayers.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/StandardLayers.java @@ -26,7 +26,6 @@ import java.util.List; *
    *
  1. "dependencies" - For non snapshot dependencies
  2. *
  3. "snapshot-dependencies" - For snapshot dependencies
  4. - *
  5. "resources" - For static resources such as HTML files
  6. *
  7. "application" - For application classes and resources
  8. *
* @@ -46,11 +45,6 @@ public abstract class StandardLayers implements Layers { */ public static final Layer SNAPSHOT_DEPENDENCIES = new Layer("snapshot-dependencies"); - /** - * The resources layer. - */ - public static final Layer RESOURCES = new Layer("resources"); - /** * The application layer. */ @@ -61,7 +55,6 @@ public abstract class StandardLayers implements Layers { List layers = new ArrayList<>(); layers.add(DEPENDENCIES); layers.add(SNAPSHOT_DEPENDENCIES); - layers.add(RESOURCES); layers.add(APPLICATION); LAYERS = Collections.unmodifiableList(layers); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/ImplicitLayerResolverTests.java b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/ImplicitLayerResolverTests.java index 91794f3744..6fe9637ea4 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/ImplicitLayerResolverTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/ImplicitLayerResolverTests.java @@ -35,15 +35,15 @@ class ImplicitLayerResolverTests { @Test void iteratorReturnsLayers() { assertThat(this.layers).containsExactly(StandardLayers.DEPENDENCIES, StandardLayers.SNAPSHOT_DEPENDENCIES, - StandardLayers.RESOURCES, StandardLayers.APPLICATION); + StandardLayers.APPLICATION); } @Test - void getLayerWhenNameInResourceLocationReturnsResourceLayer() { - assertThat(this.layers.getLayer("META-INF/resources/logo.gif")).isEqualTo(StandardLayers.RESOURCES); - assertThat(this.layers.getLayer("resources/logo.gif")).isEqualTo(StandardLayers.RESOURCES); - assertThat(this.layers.getLayer("static/logo.gif")).isEqualTo(StandardLayers.RESOURCES); - assertThat(this.layers.getLayer("public/logo.gif")).isEqualTo(StandardLayers.RESOURCES); + void getLayerWhenNameInResourceLocationReturnsApplicationLayer() { + assertThat(this.layers.getLayer("META-INF/resources/logo.gif")).isEqualTo(StandardLayers.APPLICATION); + assertThat(this.layers.getLayer("resources/logo.gif")).isEqualTo(StandardLayers.APPLICATION); + assertThat(this.layers.getLayer("static/logo.gif")).isEqualTo(StandardLayers.APPLICATION); + assertThat(this.layers.getLayer("public/logo.gif")).isEqualTo(StandardLayers.APPLICATION); } @Test diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/packaging.adoc b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/packaging.adoc index 7d35ce54cc..52a63768fc 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/packaging.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/docs/asciidoc/packaging.adoc @@ -102,11 +102,10 @@ By default, the following layers are created: * `dependencies` for any dependency whose version does not contain `SNAPSHOT`. * `snapshot-dependencies` for any dependency whose version contains `SNAPSHOT`. -* `resources` for static resources at the default locations, i.e. `META-INF/resources/`, `resources/`, `static/`, `public/`. -* `application` for any other classes and resources. +* `application` for application classes and resources. The layers order is important as it determines how likely previous layers can be cached when part of the application changes. -The default order is `dependencies`, `snapshot-dependencies`, `resources`, and `application`. +The default order is `dependencies`, `snapshot-dependencies`, and `application`. Content that is least likely to change should be added first, followed by layers that are more likely to change. @@ -149,7 +148,6 @@ The following example shows what the implicit layer configuration described abov dependencies snapshot-dependencies - resources application @@ -165,14 +163,6 @@ The following example shows what the implicit layer configuration described abov - - - META-INF/resources/** - resources/** - static/** - public/** - - ** @@ -184,7 +174,7 @@ The following example shows what the implicit layer configuration described abov Each `layer-content` element defines a strategy to include or exclude an entry of the jar in a layer. When an entry matches a strategy, it is included in the layer and further strategies are ignored. -This is illustrated by the `dependencies` and `application` layers that have a "catch-all" include filter used to add any libraries or classes that were not processed by previous strategies. +This is illustrated by the `dependencies` layer that has a "catch-all" include filter used to add any libraries that were not processed by previous strategies. The content of a `libraries` layer can be customized using filters to `include` or `exclude` based on the dependency coordinates. The format is `groupId:artifactId[:version]`.