Fix repackaging of jars with non-default compression configuration

Previously, if a jar that used custom compression configuration was
repackaged, a failure may occur if an entry in the repackaged jar had
a different compressed size to the entry in the source jar.

This commit updates JarWriter to clear the input entry's compressed
size (by setting it to -1) so that the repackaged entry's compressed
size does not have to match that of the input entry.

Closes gh-13720
pull/13755/head
Andy Wilkinson 6 years ago
parent 9a49e8ef73
commit a50646b7cc

@ -140,6 +140,9 @@ public class JarWriter implements LoaderClassesWriter {
inputStream = new ZipHeaderPeekInputStream(
jarFile.getInputStream(entry));
}
else {
entry.setCompressedSize(-1);
}
EntryWriter entryWriter = new InputStreamEntryWriter(inputStream, true);
JarEntry transformedEntry = entryTransformer.transform(entry);
if (transformedEntry != null) {

@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 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.
@ -18,15 +18,19 @@ package org.springframework.boot.loader.tools;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Calendar;
import java.util.Random;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.junit.Before;
import org.junit.Rule;
@ -613,6 +617,28 @@ public class RepackagerTests {
}
}
@Test
public void jarThatUsesCustomCompressionConfigurationCanBeRepackaged()
throws IOException {
File source = this.temporaryFolder.newFile("source.jar");
ZipOutputStream output = new ZipOutputStream(new FileOutputStream(source)) {
{
this.def = new Deflater(Deflater.NO_COMPRESSION, true);
}
};
byte[] data = new byte[1024 * 1024];
new Random().nextBytes(data);
ZipEntry entry = new ZipEntry("entry.dat");
output.putNextEntry(entry);
output.write(data);
output.closeEntry();
output.close();
File dest = this.temporaryFolder.newFile("dest.jar");
Repackager repackager = new Repackager(source);
repackager.setMainClass("com.example.Main");
repackager.repackage(dest, NO_LIBRARIES);
}
private boolean hasLauncherClasses(File file) throws IOException {
return hasEntry(file, "org/springframework/boot/")
&& hasEntry(file, "org/springframework/boot/loader/JarLauncher.class");

Loading…
Cancel
Save