Configure assemble to depend upon bootJar or bootWar

Closes gh-8824
This commit is contained in:
Andy Wilkinson 2017-04-28 16:48:48 +01:00
parent 0a8494ec74
commit 762a13e84f
13 changed files with 198 additions and 8 deletions

View File

@ -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 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`]. 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 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`]. 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]] [[packaging-executable-configuring]]
=== Configuring executable archive packaging === Configuring executable archive packaging

View File

@ -14,13 +14,15 @@ plugin:
executable, fat jar for the project. The jar will contain everything on the runtime 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 classpath of the main source set; classes are packaged in `BOOT-INF/classes` and jars
are packaged in `BOOT-INF/lib` 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. 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. 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. 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 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 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`. 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. 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. `bootWar` task.

View File

@ -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'
}

View File

@ -24,6 +24,7 @@ import org.gradle.api.Plugin;
import org.gradle.api.Project; import org.gradle.api.Project;
import org.gradle.api.file.FileCollection; import org.gradle.api.file.FileCollection;
import org.gradle.api.internal.artifacts.publish.ArchivePublishArtifact; 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.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSet;
@ -52,12 +53,23 @@ final class JavaPluginAction implements PluginApplicationAction {
@Override @Override
public void execute(Project project) { public void execute(Project project) {
disableJarTask(project);
configureBuildTask(project);
BootJar bootJar = configureBootJarTask(project); BootJar bootJar = configureBootJarTask(project);
configureArtifactPublication(project, bootJar); configureArtifactPublication(project, bootJar);
configureBootRunTask(project); configureBootRunTask(project);
configureUtf8Encoding(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) { private BootJar configureBootJarTask(Project project) {
BootJar bootJar = project.getTasks().create(SpringBootPlugin.BOOT_JAR_TASK_NAME, BootJar bootJar = project.getTasks().create(SpringBootPlugin.BOOT_JAR_TASK_NAME,
BootJar.class); BootJar.class);

View File

@ -16,8 +16,10 @@
package org.springframework.boot.gradle.plugin; package org.springframework.boot.gradle.plugin;
import org.gradle.api.Buildable;
import org.gradle.api.artifacts.PublishArtifact; import org.gradle.api.artifacts.PublishArtifact;
import org.gradle.api.artifacts.PublishArtifactSet; 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 * 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 * @author Andy Wilkinson
*/ */
final class SinglePublishedArtifact { final class SinglePublishedArtifact implements Buildable {
private final PublishArtifactSet artifacts; private final PublishArtifactSet artifacts;
@ -43,4 +45,9 @@ final class SinglePublishedArtifact {
} }
} }
@Override
public TaskDependency getBuildDependencies() {
return this.currentArtifact.getBuildDependencies();
}
} }

View File

@ -45,6 +45,7 @@ class WarPluginAction implements PluginApplicationAction {
@Override @Override
public void execute(Project project) { 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 bootWar = project.getTasks().create(SpringBootPlugin.BOOT_WAR_TASK_NAME,
BootWar.class); BootWar.class);
bootWar.providedClasspath(providedRuntimeConfiguration(project)); bootWar.providedClasspath(providedRuntimeConfiguration(project));

View File

@ -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();
}
} }

View File

@ -16,6 +16,10 @@
package org.springframework.boot.gradle.plugin; 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.Rule;
import org.junit.Test; import org.junit.Test;
@ -79,4 +83,23 @@ public class JavaPluginActionIntegrationTests {
.contains("compileTestJava = UTF-8"); .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"));
}
} }

View File

@ -16,6 +16,10 @@
package org.springframework.boot.gradle.plugin; 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.Rule;
import org.junit.Test; import org.junit.Test;
@ -59,4 +63,23 @@ public class WarPluginActionIntegrationTests {
.getOutput()).contains("bootWeb exists = true"); .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"));
}
} }

View File

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

View File

@ -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
}

View File

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

View File

@ -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
}