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 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
@ -164,4 +189,4 @@ manifest to set the `Main-Class` attribute:
[source,groovy,indent=0,subs="verbatim"] [source,groovy,indent=0,subs="verbatim"]
---- ----
include::../gradle/packaging/boot-war-properties-launcher.gradle[tags=properties-launcher] include::../gradle/packaging/boot-war-properties-launcher.gradle[tags=properties-launcher]
---- ----

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

@ -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.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);

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

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

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

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

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