Commit 341615d7 authored by Scott Frederick's avatar Scott Frederick

Merge branch '2.3.x'

Closes gh-23000
parents b6082056 3f80638a
...@@ -8351,6 +8351,10 @@ For Gradle, refer to the {spring-boot-gradle-plugin-docs}#packaging-layered-jars ...@@ -8351,6 +8351,10 @@ For Gradle, refer to the {spring-boot-gradle-plugin-docs}#packaging-layered-jars
==== Writing the Dockerfile ==== Writing the Dockerfile
When you create a jar containing the layers index file, the `spring-boot-jarmode-layertools` jar will be added as a dependency to your jar. When you create a jar containing the layers index file, the `spring-boot-jarmode-layertools` jar will be added as a dependency to your jar.
With this jar on the classpath, you can launch your application in a special mode which allows the bootstrap code to run something entirely different from your application, for example, something that extracts the layers. With this jar on the classpath, you can launch your application in a special mode which allows the bootstrap code to run something entirely different from your application, for example, something that extracts the layers.
CAUTION: The `layertools` mode can not be used with a <<deployment.adoc#deployment-install, fully executable Spring Boot archive>> that includes a launch script.
Disable launch script configuration when building a jar file that is intended to be used with `layertools`.
Here’s how you can launch your jar with a `layertools` jar mode: Here’s how you can launch your jar with a `layertools` jar mode:
[source] [source]
......
...@@ -27,6 +27,7 @@ import java.util.Map; ...@@ -27,6 +27,7 @@ import java.util.Map;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import org.springframework.util.Assert;
import org.springframework.util.StreamUtils; import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
...@@ -66,6 +67,8 @@ class ExtractCommand extends Command { ...@@ -66,6 +67,8 @@ class ExtractCommand extends Command {
} }
try (ZipInputStream zip = new ZipInputStream(new FileInputStream(this.context.getJarFile()))) { try (ZipInputStream zip = new ZipInputStream(new FileInputStream(this.context.getJarFile()))) {
ZipEntry entry = zip.getNextEntry(); ZipEntry entry = zip.getNextEntry();
Assert.state(entry != null, "File '" + this.context.getJarFile().toString()
+ "' is not compatible with layertools; ensure jar file is valid and launch script is not enabled");
while (entry != null) { while (entry != null) {
if (!entry.isDirectory()) { if (!entry.isDirectory()) {
String layer = this.layers.getLayer(entry); String layer = this.layers.getLayer(entry);
......
...@@ -18,6 +18,7 @@ package org.springframework.boot.jarmode.layertools; ...@@ -18,6 +18,7 @@ package org.springframework.boot.jarmode.layertools;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
...@@ -33,6 +34,7 @@ import org.mockito.Mock; ...@@ -33,6 +34,7 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
/** /**
...@@ -99,6 +101,19 @@ class ExtractCommandTests { ...@@ -99,6 +101,19 @@ class ExtractCommandTests {
assertThat(new File(this.extract, "c/c/c.jar")).exists(); assertThat(new File(this.extract, "c/c/c.jar")).exists();
} }
@Test
void runWithJarFileContainingNoEntriesFails() throws IOException {
File file = new File(this.temp, "empty.jar");
FileWriter writer = new FileWriter(file);
writer.write("text");
writer.flush();
given(this.context.getJarFile()).willReturn(file);
given(this.context.getWorkingDir()).willReturn(this.extract);
assertThatIllegalStateException()
.isThrownBy(() -> this.command.run(Collections.emptyMap(), Collections.emptyList()))
.withMessageContaining("not compatible with layertools");
}
private File createJarFile(String name) throws IOException { private File createJarFile(String name) throws IOException {
File file = new File(this.temp, name); File file = new File(this.temp, name);
try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file))) { try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file))) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment