mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-08-29 03:06:45 +08:00
Fail with Gradle bootBuildImage and war packaging
Prior to this commit, running the bootBuildImage Gradle task on a project configured for war packaging would result in a jar file being built and used in the image instead of the war file. With this commit an error will be thrown from the plugin in this case. Fixes gh-24521
This commit is contained in:
parent
29300530c6
commit
0e5df2296e
@ -1,6 +1,6 @@
|
||||
[[build-image]]
|
||||
== Packaging OCI Images
|
||||
The plugin can create an https://github.com/opencontainers/image-spec[OCI image] from executable jars using https://buildpacks.io[Cloud Native Buildpacks] (CNB).
|
||||
The plugin can create an https://github.com/opencontainers/image-spec[OCI image] from an executable jar file using https://buildpacks.io[Cloud Native Buildpacks] (CNB).
|
||||
Images can be built using the `bootBuildImage` task.
|
||||
|
||||
NOTE: For security reasons, images build and run as non-root users.
|
||||
@ -8,6 +8,8 @@ See the {buildpacks-reference}/reference/spec/platform-api/#users[CNB specificat
|
||||
|
||||
The task is automatically created when the `java` plugin is applied and is an instance of {boot-build-image-javadoc}[`BootBuildImage`].
|
||||
|
||||
NOTE: The `bootBuildImage` task is not supported with projects using <<packaging-executable-wars, war packaging>>.
|
||||
|
||||
NOTE: The `bootBuildImage` task can not be used with a <<packaging-executable-configuring-launch-script, fully executable Spring Boot archive>> that includes a launch script.
|
||||
Disable launch script configuration in the `bootJar` task when building a jar file that is intended to be used with `bootBuildImage`.
|
||||
|
||||
|
@ -22,11 +22,13 @@ import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.ConfigurationContainer;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.file.RegularFile;
|
||||
import org.gradle.api.internal.artifacts.dsl.LazyPublishArtifact;
|
||||
import org.gradle.api.plugins.BasePlugin;
|
||||
import org.gradle.api.plugins.WarPlugin;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootBuildImage;
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootWar;
|
||||
|
||||
/**
|
||||
@ -51,6 +53,7 @@ class WarPluginAction implements PluginApplicationAction {
|
||||
@Override
|
||||
public void execute(Project project) {
|
||||
disableWarTask(project);
|
||||
disableBootBuildImageTask(project);
|
||||
TaskProvider<BootWar> bootWar = configureBootWarTask(project);
|
||||
configureArtifactPublication(bootWar);
|
||||
}
|
||||
@ -59,6 +62,11 @@ class WarPluginAction implements PluginApplicationAction {
|
||||
project.getTasks().named(WarPlugin.WAR_TASK_NAME).configure((war) -> war.setEnabled(false));
|
||||
}
|
||||
|
||||
private void disableBootBuildImageTask(Project project) {
|
||||
project.getTasks().named(SpringBootPlugin.BOOT_BUILD_IMAGE_TASK_NAME, BootBuildImage.class)
|
||||
.configure((buildImage) -> buildImage.getJar().set((RegularFile) null));
|
||||
}
|
||||
|
||||
private TaskProvider<BootWar> configureBootWarTask(Project project) {
|
||||
return project.getTasks().register(SpringBootPlugin.BOOT_WAR_TASK_NAME, BootWar.class, (bootWar) -> {
|
||||
bootWar.setGroup(BasePlugin.BUILD_GROUP);
|
||||
|
@ -21,6 +21,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.JavaVersion;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
@ -79,6 +80,7 @@ public class BootBuildImage extends DefaultTask {
|
||||
* @return the jar property
|
||||
*/
|
||||
@Input
|
||||
@Optional
|
||||
public RegularFileProperty getJar() {
|
||||
return this.jar;
|
||||
}
|
||||
@ -226,6 +228,9 @@ public class BootBuildImage extends DefaultTask {
|
||||
|
||||
@TaskAction
|
||||
void buildImage() throws DockerEngineException, IOException {
|
||||
if (!this.jar.isPresent()) {
|
||||
throw new GradleException("Executable jar file required for building image");
|
||||
}
|
||||
Builder builder = new Builder();
|
||||
BuildRequest request = createRequest();
|
||||
builder.build(request);
|
||||
|
@ -153,6 +153,36 @@ class BootBuildImageIntegrationTests {
|
||||
.containsPattern("example/Invalid-Image-Name");
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void failsWithWarPackaging() {
|
||||
writeMainClass();
|
||||
writeLongNameResource();
|
||||
BuildResult result = this.gradleBuild.buildAndFail("bootBuildImage", "-PapplyWarPlugin");
|
||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.FAILED);
|
||||
assertThat(result.getOutput()).contains("Executable jar file required for building image");
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void buildsImageWithWarPackagingAndJarConfiguration() throws IOException {
|
||||
writeMainClass();
|
||||
writeLongNameResource();
|
||||
BuildResult result = this.gradleBuild.build("bootBuildImage");
|
||||
String projectName = this.gradleBuild.getProjectDir().getName();
|
||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(result.getOutput()).contains("docker.io/library/" + projectName);
|
||||
assertThat(result.getOutput()).contains("paketo-buildpacks/builder");
|
||||
File buildLibs = new File(this.gradleBuild.getProjectDir(), "build/libs");
|
||||
assertThat(buildLibs.listFiles())
|
||||
.containsExactly(new File(buildLibs, this.gradleBuild.getProjectDir().getName() + ".war"));
|
||||
ImageReference imageReference = ImageReference.of(ImageName.of(projectName));
|
||||
try (GenericContainer<?> container = new GenericContainer<>(imageReference.toString())) {
|
||||
container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start();
|
||||
}
|
||||
finally {
|
||||
new DockerApi().image().remove(imageReference, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeMainClass() {
|
||||
File examplePackage = new File(this.gradleBuild.getProjectDir(), "src/main/java/example");
|
||||
examplePackage.mkdirs();
|
||||
|
@ -0,0 +1,11 @@
|
||||
plugins {
|
||||
id 'war'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootBuildImage {
|
||||
jar = bootWar.archiveFile
|
||||
}
|
||||
|
||||
sourceCompatibility = '1.8'
|
||||
targetCompatibility = '1.8'
|
@ -3,5 +3,9 @@ plugins {
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
if (project.hasProperty('applyWarPlugin')) {
|
||||
apply plugin: 'war'
|
||||
}
|
||||
|
||||
sourceCompatibility = '1.8'
|
||||
targetCompatibility = '1.8'
|
||||
|
Loading…
Reference in New Issue
Block a user