Fail on layertools extract with launch script

This commit adds a check to the `layertools extract` command to
ensure that the jar file being processed is readable and has a
valid directory.

Fixes gh-22993
This commit is contained in:
Scott Frederick 2020-08-18 17:06:31 -05:00
parent 2b1b096fac
commit 3f80638a36
3 changed files with 22 additions and 0 deletions

View File

@ -8235,6 +8235,10 @@ For Gradle, refer to the {spring-boot-gradle-plugin-docs}#packaging-layered-jars
==== 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.
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`.
Heres how you can launch your jar with a `layertools` jar mode:
[source]

View File

@ -27,6 +27,7 @@ import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.springframework.util.Assert;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
@ -66,6 +67,8 @@ class ExtractCommand extends Command {
}
try (ZipInputStream zip = new ZipInputStream(new FileInputStream(this.context.getJarFile()))) {
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) {
if (!entry.isDirectory()) {
String layer = this.layers.getLayer(entry);

View File

@ -18,6 +18,7 @@ package org.springframework.boot.jarmode.layertools;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
@ -32,6 +33,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.mockito.BDDMockito.given;
/**
@ -95,6 +97,19 @@ class ExtractCommandTests {
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 {
File file = new File(this.temp, name);
try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file))) {