Browse Source

Remove unused SHA-1 hash from UNPACK markers

In BootZipCopyAction and AbstractJarWriter, SHA-1 hash is calculated for
stored entries requiring unpack and set as entry comment. However, the
hash isn't used anywhere, just the marker prefix 'UNPACK:' is checked.

This commit removes the unnecessary SHA-1 hash calculation which reads
the file completely in memory, potentially three times in extreme cases.
Now the comment is simply set to 'UNPACK:' without any hash, improving
performance.

See gh-46520

Signed-off-by: Hyunjoon Choi <hyunjoon@example.com>
Signed-off-by: academey <academey@gmail.com>
pull/47395/head
academey 5 months ago committed by Andy Wilkinson
parent
commit
d5717b71ab
  1. 23
      build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java
  2. 23
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/AbstractJarWriter.java
  3. 3
      loader/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/AbstractPackagerTests.java

23
build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java

@ -23,13 +23,10 @@ import java.io.InputStream; @@ -23,13 +23,10 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Collection;
import java.util.HashMap;
import java.util.HexFormat;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@ -585,36 +582,24 @@ class BootZipCopyAction implements CopyAction { @@ -585,36 +582,24 @@ class BootZipCopyAction implements CopyAction {
private static final int BUFFER_SIZE = 32 * 1024;
private final @Nullable MessageDigest messageDigest;
private final boolean unpack;
private final CRC32 crc = new CRC32();
private long size;
StoredEntryPreparator(InputStream inputStream, boolean unpack) throws IOException {
this.messageDigest = (unpack) ? sha1Digest() : null;
this.unpack = unpack;
try (inputStream) {
load(inputStream);
}
}
private static MessageDigest sha1Digest() {
try {
return MessageDigest.getInstance("SHA-1");
}
catch (NoSuchAlgorithmException ex) {
throw new IllegalStateException(ex);
}
}
private void load(InputStream inputStream) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
this.crc.update(buffer, 0, bytesRead);
if (this.messageDigest != null) {
this.messageDigest.update(buffer, 0, bytesRead);
}
this.size += bytesRead;
}
}
@ -624,8 +609,8 @@ class BootZipCopyAction implements CopyAction { @@ -624,8 +609,8 @@ class BootZipCopyAction implements CopyAction {
entry.setCompressedSize(this.size);
entry.setCrc(this.crc.getValue());
entry.setMethod(ZipEntry.STORED);
if (this.messageDigest != null) {
entry.setComment("UNPACK:" + HexFormat.of().formatHex(this.messageDigest.digest()));
if (this.unpack) {
entry.setComment("UNPACK:");
}
}

23
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/AbstractJarWriter.java

@ -24,12 +24,9 @@ import java.io.OutputStream; @@ -24,12 +24,9 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.HexFormat;
import java.util.Set;
import java.util.function.Function;
import java.util.jar.JarEntry;
@ -320,36 +317,24 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { @@ -320,36 +317,24 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
private static final int BUFFER_SIZE = 32 * 1024;
private final @Nullable MessageDigest messageDigest;
private final boolean unpack;
private final CRC32 crc = new CRC32();
private long size;
StoredEntryPreparator(InputStream inputStream, boolean unpack) throws IOException {
this.messageDigest = (unpack) ? sha1Digest() : null;
this.unpack = unpack;
try (inputStream) {
load(inputStream);
}
}
private static MessageDigest sha1Digest() {
try {
return MessageDigest.getInstance("SHA-1");
}
catch (NoSuchAlgorithmException ex) {
throw new IllegalStateException(ex);
}
}
private void load(InputStream inputStream) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
this.crc.update(buffer, 0, bytesRead);
if (this.messageDigest != null) {
this.messageDigest.update(buffer, 0, bytesRead);
}
this.size += bytesRead;
}
}
@ -359,8 +344,8 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { @@ -359,8 +344,8 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
entry.setCompressedSize(this.size);
entry.setCrc(this.crc.getValue());
entry.setMethod(ZipEntry.STORED);
if (this.messageDigest != null) {
entry.setComment("UNPACK:" + HexFormat.of().formatHex(this.messageDigest.digest()));
if (this.unpack) {
entry.setComment("UNPACK:");
}
}

3
loader/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/AbstractPackagerTests.java

@ -208,8 +208,7 @@ abstract class AbstractPackagerTests<P extends Packager> { @@ -208,8 +208,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
ZipEntry entry = getPackagedEntry("BOOT-INF/lib/" + libJarFile.getName());
assertThat(entry.getTime()).isEqualTo(JAN_1_1985);
entry = getPackagedEntry("BOOT-INF/lib/" + libJarFileToUnpack.getName());
assertThat(entry.getComment()).startsWith("UNPACK:");
assertThat(entry.getComment()).hasSize(47);
assertThat(entry.getComment()).isEqualTo("UNPACK:");
}
@Test

Loading…
Cancel
Save