Leave jar and war tasks enabled but configured with a classifier
Closes gh-23797
This commit is contained in:
@@ -44,37 +44,37 @@ NOTE: `providedRuntime` is preferred to Gradle's `compileOnly` configuration as,
|
||||
|
||||
|
||||
|
||||
[[packaging-executable-and-normal]]
|
||||
=== Packaging Executable and Normal Archives
|
||||
By default, when the `bootJar` or `bootWar` tasks are configured, the `jar` or `war` tasks are disabled.
|
||||
A project can be configured to build both an executable archive and a normal archive at the same time by enabling the `jar` or `war` task:
|
||||
[[packaging-executable-and-plain]]
|
||||
=== Packaging Executable and Plain Archives
|
||||
By default, when the `bootJar` or `bootWar` tasks are configured, the `jar` or `war` tasks are configured to use `plain` as the convention for their archive classifier.
|
||||
This ensures that `bootJar` and `jar` or `bootWar` and `war` have different output locations, allowing both the executable archive and the plain archive to be built at the same time.
|
||||
|
||||
If you prefer that its the executable archive, rather than the plain archive, that uses a classifier, configure the classifiers as shown in the following example for the `jar` and `bootJar` tasks:
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
|
||||
.Groovy
|
||||
----
|
||||
include::../gradle/packaging/boot-jar-and-jar.gradle[tags=enable-jar]
|
||||
include::../gradle/packaging/boot-jar-and-jar-classifiers.gradle[tags=classifiers]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
include::../gradle/packaging/boot-jar-and-jar.gradle.kts[tags=enable-jar]
|
||||
include::../gradle/packaging/boot-jar-and-jar-classifiers.gradle.kts[tags=classifiers]
|
||||
----
|
||||
|
||||
|
||||
To avoid the executable archive and the normal archive from being written to the same location, one or the other should be configured to use a different location.
|
||||
One way to do so is by configuring a classifier:
|
||||
Alternatively, if you prefer that the plain archive isn't built at all, disable its task as shown in the following example for the `jar` task:
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,attributes",role="primary"]
|
||||
.Groovy
|
||||
----
|
||||
include::../gradle/packaging/boot-jar-and-jar.gradle[tags=classifier]
|
||||
include::../gradle/packaging/only-boot-jar.gradle[tags=disable-jar]
|
||||
----
|
||||
|
||||
[source,kotlin,indent=0,subs="verbatim,attributes",role="secondary"]
|
||||
.Kotlin
|
||||
----
|
||||
include::../gradle/packaging/boot-jar-and-jar.gradle.kts[tags=classifier]
|
||||
include::../gradle/packaging/only-boot-jar.gradle.kts[tags=disable-jar]
|
||||
----
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ When Gradle's {java-plugin}[`java` plugin] is applied to a project, the Spring B
|
||||
1. Creates a {boot-jar-javadoc}[`BootJar`] task named `bootJar` that will create an executable, fat jar for the project.
|
||||
The jar will contain everything on the runtime classpath of the main source set; classes are packaged in `BOOT-INF/classes` and jars are packaged in `BOOT-INF/lib`
|
||||
2. Configures the `assemble` task to depend on the `bootJar` task.
|
||||
3. Disables the `jar` task.
|
||||
3. Configures the `jar` task to use `plain` as the convention for its archive classifier.
|
||||
4. Creates a {boot-build-image-javadoc}[`BootBuildImage`] task named `bootBuildImage` that will create a OCI image using a https://buildpacks.io[buildpack].
|
||||
5. Creates a {boot-run-javadoc}[`BootRun`] task named `bootRun` that can be used to run your application.
|
||||
6. Creates a configuration named `bootArchives` that contains the artifact produced by the `bootJar` task.
|
||||
@@ -39,7 +39,7 @@ When Gradle's {war-plugin}[`war` plugin] is applied to a project, the Spring Boo
|
||||
1. Creates a {boot-war-javadoc}[`BootWar`] task named `bootWar` that will create an executable, fat war for the project.
|
||||
In addition to the standard packaging, everything in the `providedRuntime` configuration will be packaged in `WEB-INF/lib-provided`.
|
||||
2. Configures the `assemble` task to depend on the `bootWar` task.
|
||||
3. Disables the `war` task.
|
||||
3. Configures the `war` task to use `plain` as the convention for its archive classifier.
|
||||
4. Configures the `bootArchives` configuration to contain the artifact produced by the `bootWar` task.
|
||||
|
||||
|
||||
|
||||
@@ -3,17 +3,15 @@ plugins {
|
||||
id 'org.springframework.boot' version '{gradle-project-version}'
|
||||
}
|
||||
|
||||
// tag::enable-jar[]
|
||||
jar {
|
||||
enabled = true
|
||||
}
|
||||
// end::enable-jar[]
|
||||
|
||||
// tag::classifier[]
|
||||
// tag::classifiers[]
|
||||
bootJar {
|
||||
classifier = 'boot'
|
||||
}
|
||||
// end::classifier[]
|
||||
|
||||
jar {
|
||||
classifier = ''
|
||||
}
|
||||
// end::classifiers[]
|
||||
|
||||
bootJar {
|
||||
mainClass = 'com.example.Application'
|
||||
@@ -5,17 +5,15 @@ plugins {
|
||||
id("org.springframework.boot") version "{gradle-project-version}"
|
||||
}
|
||||
|
||||
// tag::enable-jar[]
|
||||
tasks.getByName<Jar>("jar") {
|
||||
enabled = true
|
||||
}
|
||||
// end::enable-jar[]
|
||||
|
||||
// tag::classifier[]
|
||||
// tag::classifiers[]
|
||||
tasks.getByName<BootJar>("bootJar") {
|
||||
classifier = "boot"
|
||||
}
|
||||
// end::classifier[]
|
||||
|
||||
tasks.getByName<Jar>("jar") {
|
||||
classifier = ""
|
||||
}
|
||||
// end::classifiers[]
|
||||
|
||||
tasks.getByName<BootJar>("bootJar") {
|
||||
mainClass.set("com.example.Application")
|
||||
@@ -0,0 +1,14 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{gradle-project-version}'
|
||||
}
|
||||
|
||||
// tag::disable-jar[]
|
||||
jar {
|
||||
enabled = false
|
||||
}
|
||||
// end::disable-jar[]
|
||||
|
||||
bootJar {
|
||||
mainClass = 'com.example.Application'
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootJar
|
||||
|
||||
plugins {
|
||||
java
|
||||
id("org.springframework.boot") version "{gradle-project-version}"
|
||||
}
|
||||
|
||||
// tag::disable-jar[]
|
||||
tasks.getByName<Jar>("jar") {
|
||||
enabled = false
|
||||
}
|
||||
// end::disable-jar[]
|
||||
|
||||
tasks.getByName<BootJar>("bootJar") {
|
||||
mainClass.set("com.example.Application")
|
||||
}
|
||||
@@ -42,6 +42,7 @@ import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
import org.gradle.api.tasks.bundling.Jar;
|
||||
import org.gradle.api.tasks.compile.JavaCompile;
|
||||
import org.gradle.jvm.toolchain.JavaToolchainService;
|
||||
import org.gradle.jvm.toolchain.JavaToolchainSpec;
|
||||
@@ -75,7 +76,7 @@ final class JavaPluginAction implements PluginApplicationAction {
|
||||
|
||||
@Override
|
||||
public void execute(Project project) {
|
||||
disableJarTask(project);
|
||||
classifyJarTask(project);
|
||||
configureBuildTask(project);
|
||||
configureDevelopmentOnlyConfiguration(project);
|
||||
TaskProvider<BootJar> bootJar = configureBootJarTask(project);
|
||||
@@ -87,8 +88,9 @@ final class JavaPluginAction implements PluginApplicationAction {
|
||||
configureAdditionalMetadataLocations(project);
|
||||
}
|
||||
|
||||
private void disableJarTask(Project project) {
|
||||
project.getTasks().named(JavaPlugin.JAR_TASK_NAME).configure((task) -> task.setEnabled(false));
|
||||
private void classifyJarTask(Project project) {
|
||||
project.getTasks().named(JavaPlugin.JAR_TASK_NAME, Jar.class)
|
||||
.configure((task) -> task.getArchiveClassifier().convention("plain"));
|
||||
}
|
||||
|
||||
private void configureBuildTask(Project project) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.SourceSetContainer;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
import org.gradle.api.tasks.bundling.War;
|
||||
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootBuildImage;
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootWar;
|
||||
@@ -54,14 +55,15 @@ class WarPluginAction implements PluginApplicationAction {
|
||||
|
||||
@Override
|
||||
public void execute(Project project) {
|
||||
disableWarTask(project);
|
||||
classifyWarTask(project);
|
||||
TaskProvider<BootWar> bootWar = configureBootWarTask(project);
|
||||
configureBootBuildImageTask(project, bootWar);
|
||||
configureArtifactPublication(bootWar);
|
||||
}
|
||||
|
||||
private void disableWarTask(Project project) {
|
||||
project.getTasks().named(WarPlugin.WAR_TASK_NAME).configure((war) -> war.setEnabled(false));
|
||||
private void classifyWarTask(Project project) {
|
||||
project.getTasks().named(WarPlugin.WAR_TASK_NAME, War.class)
|
||||
.configure((war) -> war.getArchiveClassifier().convention("plain"));
|
||||
}
|
||||
|
||||
private TaskProvider<BootWar> configureBootWarTask(Project project) {
|
||||
|
||||
@@ -171,14 +171,34 @@ class PackagingDocumentationTests {
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void bootJarAndJar() {
|
||||
this.gradleBuild.script("src/docs/gradle/packaging/boot-jar-and-jar").build("assemble");
|
||||
File jar = new File(this.gradleBuild.getProjectDir(),
|
||||
void onlyBootJar() throws IOException {
|
||||
this.gradleBuild.script("src/docs/gradle/packaging/only-boot-jar").build("assemble");
|
||||
File plainJar = new File(this.gradleBuild.getProjectDir(),
|
||||
"build/libs/" + this.gradleBuild.getProjectDir().getName() + "-plain.jar");
|
||||
assertThat(plainJar).doesNotExist();
|
||||
File bootJar = new File(this.gradleBuild.getProjectDir(),
|
||||
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
|
||||
assertThat(jar).isFile();
|
||||
assertThat(bootJar).isFile();
|
||||
try (JarFile jar = new JarFile(bootJar)) {
|
||||
assertThat(jar.getEntry("BOOT-INF/")).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void classifiedBootJar() throws IOException {
|
||||
this.gradleBuild.script("src/docs/gradle/packaging/boot-jar-and-jar-classifiers").build("assemble");
|
||||
File plainJar = new File(this.gradleBuild.getProjectDir(),
|
||||
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
|
||||
assertThat(plainJar).isFile();
|
||||
try (JarFile jar = new JarFile(plainJar)) {
|
||||
assertThat(jar.getEntry("BOOT-INF/")).isNull();
|
||||
}
|
||||
File bootJar = new File(this.gradleBuild.getProjectDir(),
|
||||
"build/libs/" + this.gradleBuild.getProjectDir().getName() + "-boot.jar");
|
||||
assertThat(bootJar).isFile();
|
||||
try (JarFile jar = new JarFile(bootJar)) {
|
||||
assertThat(jar.getEntry("BOOT-INF/")).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@@ -92,10 +92,14 @@ class JavaPluginActionIntegrationTests {
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void assembleRunsBootJarAndJarIsSkipped() {
|
||||
void assembleRunsBootJarAndJar() {
|
||||
BuildResult result = this.gradleBuild.build("assemble");
|
||||
assertThat(result.task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(result.task(":jar").getOutcome()).isEqualTo(TaskOutcome.SKIPPED);
|
||||
assertThat(result.task(":jar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
File buildLibs = new File(this.gradleBuild.getProjectDir(), "build/libs");
|
||||
assertThat(buildLibs.listFiles()).containsExactlyInAnyOrder(
|
||||
new File(buildLibs, this.gradleBuild.getProjectDir().getName() + ".jar"),
|
||||
new File(buildLibs, this.gradleBuild.getProjectDir().getName() + "-plain.jar"));
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
@@ -105,17 +109,6 @@ class JavaPluginActionIntegrationTests {
|
||||
assertThat(result.getOutput()).contains("Main class name has not been configured and it could not be resolved");
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void jarAndBootJarCanBothBeBuilt() {
|
||||
BuildResult result = this.gradleBuild.build("assemble");
|
||||
assertThat(result.task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(result.task(":jar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
File buildLibs = new File(this.gradleBuild.getProjectDir(), "build/libs");
|
||||
assertThat(buildLibs.listFiles()).containsExactlyInAnyOrder(
|
||||
new File(buildLibs, this.gradleBuild.getProjectDir().getName() + ".jar"),
|
||||
new File(buildLibs, this.gradleBuild.getProjectDir().getName() + "-boot.jar"));
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void additionalMetadataLocationsConfiguredWhenProcessorIsPresent() throws IOException {
|
||||
createMinimalMainSource();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@@ -50,21 +50,14 @@ class WarPluginActionIntegrationTests {
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void assembleRunsBootWarAndWarIsSkipped() {
|
||||
BuildResult result = this.gradleBuild.build("assemble");
|
||||
assertThat(result.task(":bootWar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(result.task(":war").getOutcome()).isEqualTo(TaskOutcome.SKIPPED);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void warAndBootWarCanBothBeBuilt() {
|
||||
void assembleRunsBootWarAndWar() {
|
||||
BuildResult result = this.gradleBuild.build("assemble");
|
||||
assertThat(result.task(":bootWar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(result.task(":war").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
File buildLibs = new File(this.gradleBuild.getProjectDir(), "build/libs");
|
||||
assertThat(buildLibs.listFiles()).containsExactlyInAnyOrder(
|
||||
new File(buildLibs, this.gradleBuild.getProjectDir().getName() + ".war"),
|
||||
new File(buildLibs, this.gradleBuild.getProjectDir().getName() + "-boot.war"));
|
||||
new File(buildLibs, this.gradleBuild.getProjectDir().getName() + "-plain.war"));
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClass = 'com.example.Application'
|
||||
classifier = 'boot'
|
||||
}
|
||||
|
||||
jar {
|
||||
enabled = true
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
plugins {
|
||||
id 'war'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootWar {
|
||||
mainClass = 'com.example.Application'
|
||||
classifier = 'boot'
|
||||
}
|
||||
|
||||
war {
|
||||
enabled = true
|
||||
}
|
||||
Reference in New Issue
Block a user