diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/AbstractJarWriter.java b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/AbstractJarWriter.java index 6e53cb09fc..0e713989ca 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/AbstractJarWriter.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/AbstractJarWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 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. @@ -265,8 +265,8 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { private void writeEntry(JarArchiveEntry entry, Library library, EntryWriter entryWriter, UnpackHandler unpackHandler) throws IOException { String name = entry.getName(); - writeParentDirectoryEntries(name); if (this.writtenEntries.add(name)) { + writeParentDirectoryEntries(name); entry.setUnixMode(name.endsWith("/") ? UNIX_DIR_MODE : UNIX_FILE_MODE); entry.getGeneralPurposeBit().useUTF8ForNames(true); if (!entry.isDirectory() && entry.getSize() == -1) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java index 1367231dcb..9f8f186b3c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 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. @@ -38,6 +38,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.loader.tools.sample.ClassWithMainMethod; import org.springframework.util.FileCopyUtils; +import org.springframework.util.StopWatch; import org.springframework.util.StringUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -198,6 +199,18 @@ class RepackagerTests extends AbstractPackagerTests { } } + @Test + void repackagingDeeplyNestedPackageIsNotProhibitivelySlow() throws IOException { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + this.testJarFile.addClass("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/Some.class", + ClassWithMainMethod.class); + Repackager repackager = createRepackager(this.testJarFile.getFile(), true); + repackager.repackage(this.destination, NO_LIBRARIES, null, null); + stopWatch.stop(); + assertThat(stopWatch.getTotalTimeMillis()).isLessThan(5000); + } + private boolean hasLauncherClasses(File file) throws IOException { return hasEntry(file, "org/springframework/boot/") && hasEntry(file, "org/springframework/boot/loader/JarLauncher.class");