mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-05 00:56:58 +08:00
Keep track of written jar entries to not duplicate them
Closes gh-40903
This commit is contained in:
parent
82d8222f56
commit
9def6f86c9
|
@ -29,6 +29,7 @@ import java.nio.file.attribute.BasicFileAttributeView;
|
|||
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;
|
||||
|
@ -251,13 +252,22 @@ class ExtractCommand extends Command {
|
|||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
@ -86,7 +88,7 @@ class ExtractCommandTests extends AbstractJarModeTests {
|
|||
catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nested
|
||||
class Extract {
|
||||
|
@ -216,6 +218,28 @@ class ExtractCommandTests extends AbstractJarModeTests {
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue
Block a user