Fix zip compression of libs in layered jars

Closes gh-19792
pull/19880/head
Andy Wilkinson 5 years ago
parent 0bd0b2a6c0
commit 288f5ceaee

@ -23,7 +23,10 @@ import java.io.StringWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.gradle.api.Action; import org.gradle.api.Action;
import org.gradle.api.file.CopySpec; import org.gradle.api.file.CopySpec;
@ -282,18 +285,29 @@ public class BootJar extends Jar implements BootArchive {
* Returns the {@link ZipCompression} that should be used when adding the file * Returns the {@link ZipCompression} that should be used when adding the file
* represented by the given {@code details} to the jar. * represented by the given {@code details} to the jar.
* <p> * <p>
* By default, any file in {@code BOOT-INF/lib/} is stored and all other files are * By default, any file in {@code BOOT-INF/lib/} or
* deflated. * {@code BOOT-INF/layers/<layer>/lib} is stored and all other files are deflated.
* @param details the details * @param details the details
* @return the compression to use * @return the compression to use
*/ */
protected ZipCompression resolveZipCompression(FileCopyDetails details) { protected ZipCompression resolveZipCompression(FileCopyDetails details) {
if (details.getRelativePath().getPathString().startsWith("BOOT-INF/lib/")) { String path = details.getRelativePath().getPathString();
return ZipCompression.STORED; for (String prefix : getLibPathPrefixes()) {
if (path.startsWith(prefix)) {
return ZipCompression.STORED;
}
} }
return ZipCompression.DEFLATED; return ZipCompression.DEFLATED;
} }
private Set<String> getLibPathPrefixes() {
if (this.layers == null) {
return Collections.singleton("BOOT-INF/lib/");
}
return StreamSupport.stream(this.layers.spliterator(), false)
.map((layer) -> "BOOT-INF/layers/" + layer + "/lib/").collect(Collectors.toSet());
}
private LaunchScriptConfiguration enableLaunchScriptIfNecessary() { private LaunchScriptConfiguration enableLaunchScriptIfNecessary() {
LaunchScriptConfiguration launchScript = this.support.getLaunchScript(); LaunchScriptConfiguration launchScript = this.support.getLaunchScript();
if (launchScript == null) { if (launchScript == null) {

@ -110,13 +110,15 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
} }
@Test @Test
void classpathJarsArePackagedBeneathLibPath() throws IOException { void classpathJarsArePackagedBeneathLibPathAndAreStored() throws IOException {
this.task.setMainClassName("com.example.Main"); this.task.setMainClassName("com.example.Main");
this.task.classpath(jarFile("one.jar"), jarFile("two.jar")); this.task.classpath(jarFile("one.jar"), jarFile("two.jar"));
executeTask(); executeTask();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) { try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getEntry(this.libPath + "one.jar")).isNotNull(); assertThat(jarFile.getEntry(this.libPath + "one.jar")).isNotNull().extracting(ZipEntry::getMethod)
assertThat(jarFile.getEntry(this.libPath + "two.jar")).isNotNull(); .isEqualTo(ZipEntry.STORED);
assertThat(jarFile.getEntry(this.libPath + "two.jar")).isNotNull().extracting(ZipEntry::getMethod)
.isEqualTo(ZipEntry.STORED);
} }
} }
@ -409,6 +411,11 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
this.libPath + "third-library.jar"); this.libPath + "third-library.jar");
} }
@Test
void libEntriesAreStored() throws IOException {
}
protected File jarFile(String name) throws IOException { protected File jarFile(String name) throws IOException {
File file = newFile(name); File file = newFile(name);
try (JarOutputStream jar = new JarOutputStream(new FileOutputStream(file))) { try (JarOutputStream jar = new JarOutputStream(new FileOutputStream(file))) {

@ -23,6 +23,7 @@ import java.io.InputStreamReader;
import java.util.List; import java.util.List;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -100,6 +101,18 @@ class BootJarTests extends AbstractBootArchiveTests<BootJar> {
.contains("BOOT-INF/layers/resources/classes/static/test.css"); .contains("BOOT-INF/layers/resources/classes/static/test.css");
} }
@Test
void whenJarIsLayeredJarsInLibAreStored() throws IOException {
try (JarFile jarFile = new JarFile(createLayeredJar())) {
assertThat(jarFile.getEntry("BOOT-INF/layers/dependencies/lib/first-library.jar").getMethod())
.isEqualTo(ZipEntry.STORED);
assertThat(jarFile.getEntry("BOOT-INF/layers/dependencies/lib/second-library.jar").getMethod())
.isEqualTo(ZipEntry.STORED);
assertThat(jarFile.getEntry("BOOT-INF/layers/snapshot-dependencies/lib/third-library-SNAPSHOT.jar")
.getMethod()).isEqualTo(ZipEntry.STORED);
}
}
@Test @Test
void whenJarIsLayeredClasspathIndexPointsToLayeredLibs() throws IOException { void whenJarIsLayeredClasspathIndexPointsToLayeredLibs() throws IOException {
try (JarFile jarFile = new JarFile(createLayeredJar())) { try (JarFile jarFile = new JarFile(createLayeredJar())) {

Loading…
Cancel
Save