diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc index a92b9f737c..483915e8ea 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc @@ -7787,8 +7787,7 @@ This layering is designed to separate code based on how likely it is to change b Library code is less likely to change between builds, so it is placed in its own layers to allow tooling to re-use the layers from cache. Application code is more likely to change between builds so it is isolated in a separate layer. -For Maven, layered jars can be created using a new `layout` type called `LAYERED_JAR`. -See the {spring-boot-maven-plugin-docs}/#goals-build-image-parameters-details-layout[layout section] for more details. +For Maven, refer to the {spring-boot-maven-plugin-docs}/#repackage-layered-jars[packaging layered jars section] for more details on creating a layered jar. For Gradle, refer to the {spring-boot-gradle-plugin-docs}/#packaging-layered-jars[packaging layered jars section] of the Gradle plugin documentation. ==== Writing the Dockerfile 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 2eeef841c1..805c56a401 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 @@ -287,3 +287,18 @@ The jar will then be split into layer folders which may include: * `snapshots-dependencies` * `dependencies` +When you create a layered jar, the `spring-boot-layertools` jar will be added as a dependency to your jar. +With this jar on the classpath, you can launch your application in a special mode which allows the bootstrap code to run something entirely different from your application, for example, something that extracts the layers. +If you wish to exclude this dependency, you can do so in the following manner: + +[source,groovy,indent=0,subs="verbatim,attributes",role="primary"] +.Groovy +---- +include::../gradle/packaging/boot-jar-layered-exclude-tools.gradle[tags=layered] +---- + +[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"] +.Kotlin +---- +include::../gradle/packaging/boot-jar-layered-exclude-tools.gradle.kts[tags=layered] +---- \ No newline at end of file diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-exclude-tools.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-exclude-tools.gradle new file mode 100644 index 0000000000..4fe2da44f4 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-exclude-tools.gradle @@ -0,0 +1,16 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '{version}' +} + +bootJar { + mainClassName 'com.example.ExampleApplication' +} + +// tag::layered[] +bootJar { + layered { + includeLayerTools = false + } +} +// end::layered[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-exclude-tools.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-exclude-tools.gradle.kts new file mode 100644 index 0000000000..8c61012da4 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-exclude-tools.gradle.kts @@ -0,0 +1,18 @@ +import org.springframework.boot.gradle.tasks.bundling.BootJar + +plugins { + java + id("org.springframework.boot") version "{version}" +} + +tasks.getByName("bootJar") { + mainClassName = "com.example.ExampleApplication" +} + +// tag::layered[] +tasks.getByName("bootJar") { + layered { + includeLayerTools = false + } +} +// end::layered[] diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java index ff7a5302e3..3069a957c4 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java @@ -40,6 +40,8 @@ import org.gradle.api.java.archives.Attributes; import org.gradle.api.specs.Spec; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.Internal; +import org.gradle.api.tasks.Nested; +import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.bundling.Jar; import org.springframework.boot.loader.tools.Layer; @@ -67,6 +69,8 @@ public class BootJar extends Jar implements BootArchive { private Layers layers; + private LayerConfiguration layerConfiguration; + private static final String BOOT_INF_LAYERS = "BOOT-INF/layers"; private final List dependencies = new ArrayList<>(); @@ -164,20 +168,33 @@ public class BootJar extends Jar implements BootArchive { action.execute(enableLaunchScriptIfNecessary()); } + @Optional + @Nested + @Input + public LayerConfiguration getLayerConfiguration() { + return this.layerConfiguration; + } + /** * Configures the archive to have layers. */ public void layered() { - this.layers = Layers.IMPLICIT; - this.bootInf.into("lib", (spec) -> spec.from((Callable) () -> { - String jarName = "spring-boot-jarmode-layertools.jar"; - InputStream stream = getClass().getClassLoader().getResourceAsStream("META-INF/jarmode/" + jarName); - File taskTmp = new File(getProject().getBuildDir(), "tmp/" + getName()); - taskTmp.mkdirs(); - File layerToolsJar = new File(taskTmp, jarName); - FileCopyUtils.copy(stream, new FileOutputStream(layerToolsJar)); - return layerToolsJar; - })); + enableLayers(); + applyLayers(); + } + + private void applyLayers() { + if (this.layerConfiguration.isIncludeLayerTools()) { + this.bootInf.into("lib", (spec) -> spec.from((Callable) () -> { + String jarName = "spring-boot-jarmode-layertools.jar"; + InputStream stream = getClass().getClassLoader().getResourceAsStream("META-INF/jarmode/" + jarName); + File taskTmp = new File(getProject().getBuildDir(), "tmp/" + getName()); + taskTmp.mkdirs(); + File layerToolsJar = new File(taskTmp, jarName); + FileCopyUtils.copy(stream, new FileOutputStream(layerToolsJar)); + return layerToolsJar; + })); + } this.bootInf.eachFile((details) -> { Layer layer = layerForFileDetails(details); if (layer != null) { @@ -188,6 +205,20 @@ public class BootJar extends Jar implements BootArchive { this.bootInf.into("", (spec) -> spec.from(createLayersIndex())); } + public void layered(Action action) { + action.execute(enableLayers()); + applyLayers(); + } + + private LayerConfiguration enableLayers() { + this.layers = Layers.IMPLICIT; + if (this.layerConfiguration == null) { + this.layerConfiguration = new LayerConfiguration(); + } + + return this.layerConfiguration; + } + private Layer layerForFileDetails(FileCopyDetails details) { String path = details.getPath(); if (path.startsWith("BOOT-INF/lib/")) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LayerConfiguration.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LayerConfiguration.java new file mode 100644 index 0000000000..1639a6f567 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LayerConfiguration.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2020 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.gradle.tasks.bundling; + +import org.gradle.api.tasks.Input; + +/** + * Encapsulates the configuration for a layered jar. + * + * @author Madhura Bhave + * @since 2.3.0 + */ +public class LayerConfiguration { + + private boolean includeLayerTools = true; + + /** + * Whether to include the layer tools jar. + * @return true if layer tools is included + */ + @Input + public boolean isIncludeLayerTools() { + return this.includeLayerTools; + } + + public void setIncludeLayerTools(boolean includeLayerTools) { + this.includeLayerTools = includeLayerTools; + } + +} 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 86c1266989..195b96ac07 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 @@ -29,6 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Integration tests for {@link BootJar}. * * @author Andy Wilkinson + * @author Madhura Bhave */ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { @@ -53,4 +54,13 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { .isEqualTo(TaskOutcome.SUCCESS); } + @TestTemplate + void notUpToDateWhenBuiltWithLayersAndToolsAndThenWithLayersAndWithoutTools() + throws InvalidRunnerConfigurationException, UnexpectedBuildFailure, IOException { + assertThat(this.gradleBuild.build("-Playered=true", "bootJar").task(":bootJar").getOutcome()) + .isEqualTo(TaskOutcome.SUCCESS); + assertThat(this.gradleBuild.build("-Playered=true", "-PexcludeTools=true", "bootJar").task(":bootJar") + .getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + } + } 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 b02f5b5c37..7f1ff89adb 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 @@ -25,6 +25,7 @@ import java.util.jar.JarFile; import java.util.stream.Collectors; import java.util.zip.ZipEntry; +import org.gradle.api.Action; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -129,6 +130,13 @@ class BootJarTests extends AbstractBootArchiveTests { assertThat(entryNames).contains("BOOT-INF/layers/dependencies/lib/spring-boot-jarmode-layertools.jar"); } + @Test + void whenJarIsLayeredAndIncludeLayerToolsIsFalseThenLayerToolsAreNotAddedToTheJar() throws IOException { + List entryNames = getEntryNames( + createLayeredJar((configuration) -> configuration.setIncludeLayerTools(false))); + assertThat(entryNames).doesNotContain("BOOT-INF/layers/dependencies/lib/spring-boot-jarmode-layertools.jar"); + } + @Test void classpathIndexPointsToBootInfLibs() throws IOException { try (JarFile jarFile = new JarFile(createPopulatedJar())) { @@ -145,13 +153,22 @@ class BootJarTests extends AbstractBootArchiveTests { return getTask().getArchiveFile().get().getAsFile(); } - private File createLayeredJar() throws IOException { + private File createLayeredJar(Action action) throws IOException { addContent(); - getTask().layered(); + if (action != null) { + getTask().layered(action); + } + else { + getTask().layered(); + } executeTask(); return getTask().getArchiveFile().get().getAsFile(); } + private File createLayeredJar() throws IOException { + return createLayeredJar(null); + } + private void addContent() throws IOException { BootJar bootJar = getTask(); bootJar.setMainClassName("com.example.Main"); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.gradle index 8d1ae66420..fb56a68e55 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.gradle @@ -11,6 +11,8 @@ bootJar { } } if (project.hasProperty('layered') && project.getProperty('layered')) { - layered() + layered { + includeLayerTools = project.hasProperty('excludeTools') && project.getProperty('excludeTools') ? false : true + } } } 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 ba7b85279d..e61a6211ee 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 @@ -397,3 +397,56 @@ This example excludes any artifact belonging to the `com.foo` group: ---- + + + +[[repackage-layered-jars]] +==== Packaging layered jars +By default, the repackaged jar contains the application's classes and dependencies in `BOOT-INF/classes` and `BOOT-INF/lib` respectively. +For cases where a docker image needs to be built from the contents of the jar, the jar format can be enhanced to support layer folders. +To use this feature, the layering feature must be enabled: + +[source,xml,indent=0,subs="verbatim,attributes"] +---- + + + + + org.springframework.boot + spring-boot-maven-plugin + {gradle-project-version} + + + true + + + + + + +---- + +When you create a layered jar, the `spring-boot-layertools` jar will be added as a dependency to your jar. +With this jar on the classpath, you can launch your application in a special mode which allows the bootstrap code to run something entirely different from your application, for example, something that extracts the layers. +If you wish to exclude this dependency, you can do so in the following manner: + +[source,xml,indent=0,subs="verbatim,attributes"] +---- + + + + + org.springframework.boot + spring-boot-maven-plugin + {gradle-project-version} + + + true + false + + + + + + +---- \ No newline at end of file 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 8541cee8c4..a1e69ef804 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 @@ -287,7 +287,21 @@ class JarIntegrationTests extends AbstractArchiveIntegrationTests { File repackaged = new File(project, "jar/target/jar-layered-0.0.1.BUILD-SNAPSHOT.jar"); assertThat(jar(repackaged)).hasEntryWithNameStartingWith("BOOT-INF/layers/application/classes/") .hasEntryWithNameStartingWith("BOOT-INF/layers/dependencies/lib/jar-release") - .hasEntryWithNameStartingWith("BOOT-INF/layers/snapshot-dependencies/lib/jar-snapshot"); + .hasEntryWithNameStartingWith("BOOT-INF/layers/snapshot-dependencies/lib/jar-snapshot") + .hasEntryWithNameStartingWith( + "BOOT-INF/layers/dependencies/lib/spring-boot-jarmode-layertools.jar"); + }); + } + + @TestTemplate + void whenJarIsRepackagedWithTheLayeredLayoutAndLayerToolsExcluded(MavenBuild mavenBuild) { + mavenBuild.project("jar-layered-no-layer-tools").execute((project) -> { + File repackaged = new File(project, "jar/target/jar-layered-0.0.1.BUILD-SNAPSHOT.jar"); + assertThat(jar(repackaged)).hasEntryWithNameStartingWith("BOOT-INF/layers/application/classes/") + .hasEntryWithNameStartingWith("BOOT-INF/layers/dependencies/lib/jar-release") + .hasEntryWithNameStartingWith("BOOT-INF/layers/snapshot-dependencies/lib/jar-snapshot") + .doesNotHaveEntryWithNameStartingWith( + "BOOT-INF/layers/dependencies/lib/spring-boot-jarmode-layertools.jar"); }); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/jar-release/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/jar-release/pom.xml new file mode 100644 index 0000000000..a06fe545f1 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/jar-release/pom.xml @@ -0,0 +1,11 @@ + + + 4.0.0 + org.springframework.boot.maven.it + jar-release + 0.0.1.RELEASE + jar + jar + Release Jar dependency + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/jar-snapshot/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/jar-snapshot/pom.xml new file mode 100644 index 0000000000..ab31e719ba --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/jar-snapshot/pom.xml @@ -0,0 +1,11 @@ + + + 4.0.0 + org.springframework.boot.maven.it + jar-snapshot + 0.0.1.BUILD-SNAPSHOT + jar + jar + Snapshot Jar dependency + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/jar/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/jar/pom.xml new file mode 100644 index 0000000000..bea5f83149 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/jar/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + org.springframework.boot.maven.it + jar-layered + 0.0.1.BUILD-SNAPSHOT + + UTF-8 + @java.version@ + @java.version@ + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + repackage + + + + true + false + + + + + + + + + + org.springframework.boot.maven.it + jar-snapshot + 0.0.1.BUILD-SNAPSHOT + + + org.springframework.boot.maven.it + jar-release + 0.0.1.RELEASE + + + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/jar/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/jar/src/main/java/org/test/SampleApplication.java new file mode 100644 index 0000000000..ca2b9a2f0e --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/jar/src/main/java/org/test/SampleApplication.java @@ -0,0 +1,24 @@ +/* + * Copyright 2012-2020 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/intTest/projects/jar-layered-no-layer-tools/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/pom.xml new file mode 100644 index 0000000000..fdd9895381 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered-no-layer-tools/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + org.springframework.boot.maven.it + aggregator + 0.0.1.BUILD-SNAPSHOT + pom + + UTF-8 + @java.version@ + @java.version@ + + + jar-snapshot + jar-release + jar + + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered/jar/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered/jar/pom.xml index 31402966ff..48b928c57c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered/jar/pom.xml +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/jar-layered/jar/pom.xml @@ -22,7 +22,9 @@ repackage - LAYERED_JAR + + true + diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java index 50c3520192..c8780a2a97 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java @@ -104,6 +104,13 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo @Parameter(defaultValue = "false") public boolean includeSystemScope; + /** + * Layer configuration with the option to exclude layer tools jar. + * @since 2.3.0 + */ + @Parameter + private Layered layered; + /** * Return a {@link Packager} configured for this MOJO. * @param

the packager type @@ -119,6 +126,10 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo getLog().info("Layout: " + this.layout); packager.setLayout(this.layout.layout()); } + if (this.layered != null && this.layered.isEnabled()) { + packager.setLayout(new LayeredJar()); + packager.setIncludeRelevantJarModeJars(this.layered.isIncludeLayerTools()); + } return packager; } @@ -158,11 +169,6 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo */ JAR(new Jar()), - /** - * Layered Jar Layout. - */ - LAYERED_JAR(new LayeredJar()), - /** * War Layout. */ diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Layered.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Layered.java new file mode 100644 index 0000000000..2c7772035a --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Layered.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2020 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; + +/** + * Layer configuration options. + * + * @author Madhura Bhave + * @since 2.3.0 + */ +public class Layered { + + private boolean enabled; + + private boolean includeLayerTools = true; + + /** + * Whether layered jar layout is enabled. + * @return true if the layered layout is enabled. + */ + public boolean isEnabled() { + return this.enabled; + } + + /** + * Whether to include the layer tools jar. + * @return true if layer tools should be included + */ + public boolean isIncludeLayerTools() { + return this.includeLayerTools; + } + +}