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 48bd2f45f2..f8fb598758 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 @@ -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] ---- diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/reacting.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/reacting.adoc index b4d58e2453..eb2383621f 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/reacting.adoc +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/asciidoc/reacting.adoc @@ -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. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-and-jar.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-and-jar-classifiers.gradle similarity index 64% rename from spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-and-jar.gradle rename to spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-and-jar-classifiers.gradle index b6e8e28739..d46f78d7ee 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-and-jar.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-and-jar-classifiers.gradle @@ -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' diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-and-jar.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-and-jar-classifiers.gradle.kts similarity index 76% rename from spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-and-jar.gradle.kts rename to spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-and-jar-classifiers.gradle.kts index 007a422dc5..ae132a181c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-and-jar.gradle.kts +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-and-jar-classifiers.gradle.kts @@ -5,17 +5,15 @@ plugins { id("org.springframework.boot") version "{gradle-project-version}" } -// tag::enable-jar[] -tasks.getByName("jar") { - enabled = true -} -// end::enable-jar[] - -// tag::classifier[] +// tag::classifiers[] tasks.getByName("bootJar") { classifier = "boot" } -// end::classifier[] + +tasks.getByName("jar") { + classifier = "" +} +// end::classifiers[] tasks.getByName("bootJar") { mainClass.set("com.example.Application") diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/only-boot-jar.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/only-boot-jar.gradle new file mode 100644 index 0000000000..6f8ef2b67c --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/only-boot-jar.gradle @@ -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' +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/only-boot-jar.gradle.kts b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/only-boot-jar.gradle.kts new file mode 100644 index 0000000000..2e6686bfb0 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/only-boot-jar.gradle.kts @@ -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") { + enabled = false +} +// end::disable-jar[] + +tasks.getByName("bootJar") { + mainClass.set("com.example.Application") +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/JavaPluginAction.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/JavaPluginAction.java index bbf66a5952..ac8ae9dee5 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/JavaPluginAction.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/JavaPluginAction.java @@ -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 = 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) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/WarPluginAction.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/WarPluginAction.java index 555e40b64a..d243ca04d7 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/WarPluginAction.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/WarPluginAction.java @@ -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 = 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 configureBootWarTask(Project project) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java index 8e374b8e15..8d612650e6 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java @@ -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 diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/JavaPluginActionIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/JavaPluginActionIntegrationTests.java index 3681f0c25d..016103a405 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/JavaPluginActionIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/JavaPluginActionIntegrationTests.java @@ -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(); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/WarPluginActionIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/WarPluginActionIntegrationTests.java index 1e062d76f6..73e7cda463 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/WarPluginActionIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/WarPluginActionIntegrationTests.java @@ -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 diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/JavaPluginActionIntegrationTests-assembleRunsBootJarAndJarIsSkipped.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/JavaPluginActionIntegrationTests-assembleRunsBootJarAndJar.gradle similarity index 100% rename from spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/JavaPluginActionIntegrationTests-assembleRunsBootJarAndJarIsSkipped.gradle rename to spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/JavaPluginActionIntegrationTests-assembleRunsBootJarAndJar.gradle diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/JavaPluginActionIntegrationTests-jarAndBootJarCanBothBeBuilt.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/JavaPluginActionIntegrationTests-jarAndBootJarCanBothBeBuilt.gradle deleted file mode 100644 index cf61891109..0000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/JavaPluginActionIntegrationTests-jarAndBootJarCanBothBeBuilt.gradle +++ /dev/null @@ -1,13 +0,0 @@ -plugins { - id 'java' - id 'org.springframework.boot' version '{version}' -} - -bootJar { - mainClass = 'com.example.Application' - classifier = 'boot' -} - -jar { - enabled = true -} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/WarPluginActionIntegrationTests-assembleRunsBootWarAndWarIsSkipped.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/WarPluginActionIntegrationTests-assembleRunsBootWarAndWar.gradle similarity index 100% rename from spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/WarPluginActionIntegrationTests-assembleRunsBootWarAndWarIsSkipped.gradle rename to spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/WarPluginActionIntegrationTests-assembleRunsBootWarAndWar.gradle diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/WarPluginActionIntegrationTests-warAndBootWarCanBothBeBuilt.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/WarPluginActionIntegrationTests-warAndBootWarCanBothBeBuilt.gradle deleted file mode 100644 index 59f033f186..0000000000 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/WarPluginActionIntegrationTests-warAndBootWarCanBothBeBuilt.gradle +++ /dev/null @@ -1,13 +0,0 @@ -plugins { - id 'war' - id 'org.springframework.boot' version '{version}' -} - -bootWar { - mainClass = 'com.example.Application' - classifier = 'boot' -} - -war { - enabled = true -}