diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle
index 70a68cc409..b434424760 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/build.gradle
@@ -15,19 +15,22 @@ configurations {
dependencies {
api(platform(project(":spring-boot-project:spring-boot-parent")))
- api(project(":spring-boot-project:spring-boot-tools:spring-boot-buildpack-platform"))
compileOnly("org.apache.maven.plugin-tools:maven-plugin-annotations")
compileOnly("org.sonatype.plexus:plexus-build-api")
+ implementation(project(":spring-boot-project:spring-boot-tools:spring-boot-buildpack-platform"))
implementation(project(":spring-boot-project:spring-boot-tools:spring-boot-loader-tools"))
implementation("org.apache.maven.shared:maven-common-artifact-filters")
implementation("org.apache.maven:maven-plugin-api")
intTestImplementation(platform(project(":spring-boot-project:spring-boot-parent")))
+ intTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-buildpack-platform"))
+ intTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
intTestImplementation("org.apache.maven.shared:maven-invoker")
intTestImplementation("org.assertj:assertj-core")
intTestImplementation("org.junit.jupiter:junit-jupiter")
+ intTestImplementation("org.testcontainers:testcontainers")
optional(platform(project(":spring-boot-project:spring-boot-parent")))
optional("org.apache.maven.plugins:maven-shade-plugin")
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java
new file mode 100644
index 0000000000..aa898f6b81
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2012-2020 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.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.maven;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.wait.strategy.Wait;
+
+import org.springframework.boot.buildpack.platform.docker.DockerApi;
+import org.springframework.boot.buildpack.platform.docker.type.ImageName;
+import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
+import org.springframework.boot.testsupport.testcontainers.DisabledIfDockerUnavailable;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration tests for the Maven plugin's image support.
+ *
+ * @author Stephane Nicoll
+ */
+@ExtendWith(MavenBuildExtension.class)
+@DisabledIfDockerUnavailable
+public class BuildImageTests extends AbstractArchiveIntegrationTests {
+
+ @TestTemplate
+ void whenBuildImageIsInvokedWithoutRepackageTheArchiveIsRepackagedOnTheFly(MavenBuild mavenBuild) {
+ mavenBuild.project("build-image").goals("package").execute((project) -> {
+ File jar = new File(project, "target/build-image-0.0.1.BUILD-SNAPSHOT.jar");
+ assertThat(jar).isFile();
+ File original = new File(project, "target/build-image-0.0.1.BUILD-SNAPSHOT.jar.original");
+ assertThat(original).doesNotExist();
+ assertThat(buildLog(project)).contains("Building image")
+ .contains("docker.io/library/build-image:0.0.1.BUILD-SNAPSHOT")
+ .contains("Successfully built image");
+ ImageReference imageReference = ImageReference.of(ImageName.of("build-image"), "0.0.1.BUILD-SNAPSHOT");
+ try (GenericContainer> container = new GenericContainer<>(imageReference.toString())) {
+ container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start();
+ }
+ finally {
+ removeImage(imageReference);
+ }
+ });
+ }
+
+ @TestTemplate
+ void whenBuildImageIsInvokedWihCustomImageName(MavenBuild mavenBuild) {
+ mavenBuild.project("build-image-custom-name").goals("package").execute((project) -> {
+ File jar = new File(project, "target/build-image-custom-name-0.0.1.BUILD-SNAPSHOT.jar");
+ assertThat(jar).isFile();
+ File original = new File(project, "target/build-image-custom-name-0.0.1.BUILD-SNAPSHOT.jar.original");
+ assertThat(original).doesNotExist();
+ assertThat(buildLog(project)).contains("Building image")
+ .contains("example.com/test/build-image:0.0.1.BUILD-SNAPSHOT").contains("Successfully built image");
+ ImageReference imageReference = ImageReference.of("example.com/test/build-image:0.0.1.BUILD-SNAPSHOT");
+ try (GenericContainer> container = new GenericContainer<>(imageReference.toString())) {
+ container.waitingFor(Wait.forLogMessage("Launched\\n", 1)).start();
+ }
+ finally {
+ removeImage(imageReference);
+ }
+ });
+ }
+
+ private void removeImage(ImageReference imageReference) {
+ try {
+ new DockerApi().image().remove(imageReference, false);
+ }
+ catch (IOException ex) {
+ throw new IllegalStateException("Failed to remove docker image " + imageReference, ex);
+ }
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-image-custom-name/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-image-custom-name/pom.xml
new file mode 100644
index 0000000000..57ec39dd84
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-image-custom-name/pom.xml
@@ -0,0 +1,34 @@
+
+
+ 4.0.0
+ org.springframework.boot.maven.it
+ build-image-custom-name
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+ @java.version@
+ @java.version@
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+
+ build-image
+
+
+
+ example.com/test/build-image:${project.version}
+
+
+
+
+
+
+
+
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-image-custom-name/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-image-custom-name/src/main/java/org/test/SampleApplication.java
new file mode 100644
index 0000000000..27259ff01a
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-image-custom-name/src/main/java/org/test/SampleApplication.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012-2020 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.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.test;
+
+public class SampleApplication {
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("Launched");
+ synchronized(args) {
+ args.wait(); // Prevent exit"
+ }
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-image/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-image/pom.xml
new file mode 100644
index 0000000000..0451a8426e
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-image/pom.xml
@@ -0,0 +1,29 @@
+
+
+ 4.0.0
+ org.springframework.boot.maven.it
+ build-image
+ 0.0.1.BUILD-SNAPSHOT
+
+ UTF-8
+ @java.version@
+ @java.version@
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+
+ build-image
+
+
+
+
+
+
+
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-image/src/main/java/org/test/SampleApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-image/src/main/java/org/test/SampleApplication.java
new file mode 100644
index 0000000000..27259ff01a
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/build-image/src/main/java/org/test/SampleApplication.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012-2020 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.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.test;
+
+public class SampleApplication {
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("Launched");
+ synchronized(args) {
+ args.wait(); // Prevent exit"
+ }
+ }
+
+}