Skip to content

Commit

Permalink
Keep track of written jar entries to not duplicate them
Browse files Browse the repository at this point in the history
Closes gh-40903
  • Loading branch information
mhalbritter committed May 27, 2024
1 parent 82d8222 commit 9def6f8
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.nio.file.attribute.FileTime;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -251,13 +252,22 @@ private void createApplication(JarStructure jarStructure, FileResolver fileResol
mkdirs(file.getParentFile());
try (JarOutputStream output = new JarOutputStream(new FileOutputStream(file), manifest)) {
EnumSet<Type> allowedTypes = EnumSet.of(Type.APPLICATION_CLASS_OR_RESOURCE, Type.META_INF);
Set<String> writtenEntries = new HashSet<>();
withJarEntries(this.context.getArchiveFile(), ((stream, jarEntry) -> {
Entry entry = jarStructure.resolve(jarEntry);
if (entry != null && allowedTypes.contains(entry.type()) && StringUtils.hasLength(entry.location())) {
JarEntry newJarEntry = createJarEntry(entry.location(), jarEntry);
output.putNextEntry(newJarEntry);
StreamUtils.copy(stream, output);
output.closeEntry();
if (writtenEntries.add(newJarEntry.getName())) {
output.putNextEntry(newJarEntry);
StreamUtils.copy(stream, output);
output.closeEntry();
}
else {
if (!newJarEntry.isDirectory()) {
throw new IllegalStateException("Duplicate jar entry '%s' from original location '%s'"
.formatted(newJarEntry.getName(), entry.originalLocation()));
}
}
}
}));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,17 @@ class ExtractCommandTests extends AbstractJarModeTests {

private static final Instant LAST_ACCESS_TIME = Instant.parse("2022-01-01T00:00:00Z");

private Manifest manifest;

private File archive;

@BeforeEach
void setUp() throws IOException {
Manifest manifest = createManifest("Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx",
this.manifest = createManifest("Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx",
"Spring-Boot-Lib: BOOT-INF/lib/", "Spring-Boot-Classes: BOOT-INF/classes/",
"Start-Class: org.example.Main", "Spring-Boot-Layers-Index: BOOT-INF/layers.idx",
"Some-Attribute: Some-Value");
this.archive = createArchive(manifest, CREATION_TIME, LAST_MODIFIED_TIME, LAST_ACCESS_TIME,
this.archive = createArchive(this.manifest, CREATION_TIME, LAST_MODIFIED_TIME, LAST_ACCESS_TIME,
"BOOT-INF/classpath.idx", "/jar-contents/classpath.idx", "BOOT-INF/layers.idx",
"/jar-contents/layers.idx", "BOOT-INF/lib/dependency-1.jar", "/jar-contents/dependency-1",
"BOOT-INF/lib/dependency-2.jar", "/jar-contents/dependency-2", "BOOT-INF/lib/dependency-3-SNAPSHOT.jar",
Expand Down Expand Up @@ -86,7 +88,7 @@ private void timeAttributes(File file) {
catch (IOException ex) {
throw new RuntimeException(ex);
}
};
}

@Nested
class Extract {
Expand Down Expand Up @@ -216,6 +218,28 @@ void shouldExtractFilesUnderMetaInf() throws IOException {
assertThat(entryNames).contains("META-INF/build-info.properties");
}

@Test
void shouldNotFailOnDuplicateDirectories() throws IOException {
File file = createArchive(ExtractCommandTests.this.manifest, "BOOT-INF/classpath.idx",
"/jar-contents/classpath.idx", "META-INF/native-image/", "/jar-contents/empty-file",
"BOOT-INF/classes/META-INF/native-image/", "/jar-contents/empty-file");
run(file);
File application = file("test/test.jar");
List<String> entryNames = getJarEntryNames(application);
assertThat(entryNames).containsExactlyInAnyOrder("META-INF/native-image/", "META-INF/MANIFEST.MF");
}

@Test
void shouldFailOnDuplicateFiles() throws IOException {
File file = createArchive(ExtractCommandTests.this.manifest, "BOOT-INF/classpath.idx",
"/jar-contents/classpath.idx", "META-INF/native-image/native-image.properties",
"/jar-contents/empty-file", "BOOT-INF/classes/META-INF/native-image/native-image.properties",
"/jar-contents/empty-file");
assertThatIllegalStateException().isThrownBy(() -> run(file))
.withMessage(
"Duplicate jar entry 'META-INF/native-image/native-image.properties' from original location 'BOOT-INF/classes/META-INF/native-image/native-image.properties'");
}

}

@Nested
Expand Down

0 comments on commit 9def6f8

Please sign in to comment.