Configure assemble to depend upon bootJar or bootWar

Closes gh-8824
pull/9032/merge
Andy Wilkinson 8 years ago
parent 0a8494ec74
commit 762a13e84f

@ -11,6 +11,8 @@ an application's dependencies and can then be run with `java -jar`.
Executable jars can be built using the `bootJar` task. The task is automatically created
when the `java` plugin is applied and is an instance of {boot-jar-javadoc}[`BootJar`].
The `assemble` task is automatically configured to depend upon the `bootJar` task so
running `assemble` (or `build`) will also run the `bootJar` task.
@ -19,6 +21,8 @@ when the `java` plugin is applied and is an instance of {boot-jar-javadoc}[`Boot
Executable wars can be built using the `bootWar` task. The task is automatically created
when the `war` plugin is applied and is an instance of {boot-war-javadoc}[`BootWar`].
The `assemble` task is automatically configured to depend upon the `bootWar` task so
running `assemble` (or `build`) will also run the `bootWar` task.
@ -43,6 +47,27 @@ web-based integration tests will fail.
[[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:
[source,groovy,indent=0,subs="verbatim"]
----
include::../gradle/packaging/boot-jar-and-jar.gradle[tags=enable-jar]
----
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:
[source,groovy,indent=0,subs="verbatim"]
----
include::../gradle/packaging/boot-jar-and-jar.gradle[tags=classifier]
----
[[packaging-executable-configuring]]
=== Configuring executable archive packaging

@ -14,13 +14,15 @@ plugin:
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. Creates a {software-component}[software component] named `bootJava` that contains the
2. Configures the `assemble` task to depend on the `bootJar` task.
3. Disables the `jar` task.
4. Creates a {software-component}[software component] named `bootJava` that contains the
archive produced by the `bootJar` task.
3. Creates a {boot-run-javadoc}[`BootRun`] task named `bootRun` that can be used to run
5. Creates a {boot-run-javadoc}[`BootRun`] task named `bootRun` that can be used to run
your application.
4. Creates a configuration named `bootArchives` that contains the artifact produced by
6. Creates a configuration named `bootArchives` that contains the artifact produced by
the `bootJar` task.
5. Configures any `JavaCompile` tasks with no configured encoding to use `UTF-8`.
7. Configures any `JavaCompile` tasks with no configured encoding to use `UTF-8`.
@ -32,9 +34,11 @@ 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. Creates a {software-component}[software component] named `bootWeb` that contains the
2. Configures the `assemble` task to depend on the `bootWar` task.
3. Disables the `war` task.
4. Creates a {software-component}[software component] named `bootWeb` that contains the
archive produced by the `bootWar` task.
3. Configures the `bootArchives` configuration to contain the artifact produced by the
5. Configures the `bootArchives` configuration to contain the artifact produced by the
`bootWar` task.

@ -0,0 +1,24 @@
buildscript {
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'org.springframework.boot'
apply plugin: 'java'
// tag::enable-jar[]
jar {
enabled = true
}
// end::enable-jar[]
// tag::classifier[]
bootJar {
classifier = 'boot'
}
// end::classifier[]
bootJar {
mainClass = 'com.example.Application'
}

@ -24,6 +24,7 @@ import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.file.FileCollection;
import org.gradle.api.internal.artifacts.publish.ArchivePublishArtifact;
import org.gradle.api.plugins.BasePlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet;
@ -52,12 +53,23 @@ final class JavaPluginAction implements PluginApplicationAction {
@Override
public void execute(Project project) {
disableJarTask(project);
configureBuildTask(project);
BootJar bootJar = configureBootJarTask(project);
configureArtifactPublication(project, bootJar);
configureBootRunTask(project);
configureUtf8Encoding(project);
}
private void disableJarTask(Project project) {
project.getTasks().getByName(JavaPlugin.JAR_TASK_NAME).setEnabled(false);
}
private void configureBuildTask(Project project) {
project.getTasks().getByName(BasePlugin.ASSEMBLE_TASK_NAME)
.dependsOn(this.singlePublishedArtifact);
}
private BootJar configureBootJarTask(Project project) {
BootJar bootJar = project.getTasks().create(SpringBootPlugin.BOOT_JAR_TASK_NAME,
BootJar.class);

@ -16,8 +16,10 @@
package org.springframework.boot.gradle.plugin;
import org.gradle.api.Buildable;
import org.gradle.api.artifacts.PublishArtifact;
import org.gradle.api.artifacts.PublishArtifactSet;
import org.gradle.api.tasks.TaskDependency;
/**
* A wrapper for a {@PublishArtifactSet} that ensures that only a single artifact is
@ -25,7 +27,7 @@ import org.gradle.api.artifacts.PublishArtifactSet;
*
* @author Andy Wilkinson
*/
final class SinglePublishedArtifact {
final class SinglePublishedArtifact implements Buildable {
private final PublishArtifactSet artifacts;
@ -43,4 +45,9 @@ final class SinglePublishedArtifact {
}
}
@Override
public TaskDependency getBuildDependencies() {
return this.currentArtifact.getBuildDependencies();
}
}

@ -45,6 +45,7 @@ class WarPluginAction implements PluginApplicationAction {
@Override
public void execute(Project project) {
project.getTasks().getByName(WarPlugin.WAR_TASK_NAME).setEnabled(false);
BootWar bootWar = project.getTasks().create(SpringBootPlugin.BOOT_WAR_TASK_NAME,
BootWar.class);
bootWar.providedClasspath(providedRuntimeConfiguration(project));

@ -173,4 +173,17 @@ public class PackagingDocumentationTests {
}
}
@Test
public void bootJarAndJar() throws IOException {
this.gradleBuild.script("src/main/gradle/packaging/boot-jar-and-jar.gradle")
.build("assemble");
File jar = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(jar).isFile();
File bootJar = new File(this.gradleBuild.getProjectDir(),
"build/libs/" + this.gradleBuild.getProjectDir().getName() + "-boot.jar");
assertThat(bootJar).isFile();
}
}

@ -16,6 +16,10 @@
package org.springframework.boot.gradle.plugin;
import java.io.File;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
@ -79,4 +83,23 @@ public class JavaPluginActionIntegrationTests {
.contains("compileTestJava = UTF-8");
}
@Test
public void assembleRunsBootJarAndJarIsSkipped() {
BuildResult result = this.gradleBuild.build("assemble");
assertThat(result.task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.task(":jar").getOutcome()).isEqualTo(TaskOutcome.SKIPPED);
}
@Test
public 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"));
}
}

@ -16,6 +16,10 @@
package org.springframework.boot.gradle.plugin;
import java.io.File;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.Rule;
import org.junit.Test;
@ -59,4 +63,23 @@ public class WarPluginActionIntegrationTests {
.getOutput()).contains("bootWeb exists = true");
}
@Test
public void assembleRunsBootWarAndWarIsSkipped() {
BuildResult result = this.gradleBuild.build("assemble");
assertThat(result.task(":bootWar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.task(":war").getOutcome()).isEqualTo(TaskOutcome.SKIPPED);
}
@Test
public void warAndBootWarCanBothBeBuilt() {
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"));
}
}

@ -0,0 +1,12 @@
buildscript {
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'org.springframework.boot'
apply plugin: 'java'
bootJar {
mainClass = 'com.example.Application'
}

@ -0,0 +1,17 @@
buildscript {
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'org.springframework.boot'
apply plugin: 'java'
bootJar {
mainClass = 'com.example.Application'
classifier = 'boot'
}
jar {
enabled = true
}

@ -0,0 +1,12 @@
buildscript {
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'org.springframework.boot'
apply plugin: 'war'
bootWar {
mainClass = 'com.example.Application'
}

@ -0,0 +1,17 @@
buildscript {
dependencies {
classpath files(pluginClasspath.split(','))
}
}
apply plugin: 'org.springframework.boot'
apply plugin: 'war'
bootWar {
mainClass = 'com.example.Application'
classifier = 'boot'
}
war {
enabled = true
}
Loading…
Cancel
Save