Preserve timestamps on loader directories
Prior to this commit, when the Maven plugin copied spring-boot-loader.jar to a repackaged archive the timestamps of class files were preserved but the timestamps of directories were not preserved. This resulted in the directories having a current timestamp. This commit copies the directory timestamps from spring-boot-loader.jar to the repackaged archive and adds tests to verify the proper behavior. See gh-20927
This commit is contained in:
parent
e83c3b87c0
commit
fa186aa15b
|
|
@ -209,13 +209,21 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
|
|||
try (JarInputStream inputStream = new JarInputStream(new BufferedInputStream(loaderJar.openStream()))) {
|
||||
JarEntry entry;
|
||||
while ((entry = inputStream.getNextJarEntry()) != null) {
|
||||
if (entry.getName().endsWith(".class")) {
|
||||
if (isDirectoryEntry(entry) || isClassEntry(entry)) {
|
||||
writeEntry(new JarArchiveEntry(entry), new InputStreamEntryWriter(inputStream));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDirectoryEntry(JarEntry entry) {
|
||||
return entry.isDirectory() && !entry.getName().equals("META-INF/");
|
||||
}
|
||||
|
||||
private boolean isClassEntry(JarEntry entry) {
|
||||
return entry.getName().endsWith(".class");
|
||||
}
|
||||
|
||||
private void writeEntry(JarArchiveEntry entry, EntryWriter entryWriter) throws IOException {
|
||||
writeEntry(entry, entryWriter, UnpackHandler.NEVER);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
|
|
@ -156,6 +159,36 @@ class RepackagerTests extends AbstractPackagerTests<Repackager> {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void allLoaderDirectoriesAndFilesUseSameTimestamp() throws IOException {
|
||||
this.testJarFile.addClass("A.class", ClassWithMainMethod.class);
|
||||
Repackager repackager = createRepackager(this.testJarFile.getFile(), true);
|
||||
Long timestamp = null;
|
||||
repackager.repackage(this.destination, NO_LIBRARIES);
|
||||
for (ZipArchiveEntry entry : getAllPackagedEntries()) {
|
||||
if (entry.getName().startsWith("org/springframework/boot/loader")) {
|
||||
if (timestamp == null) {
|
||||
timestamp = entry.getTime();
|
||||
}
|
||||
else {
|
||||
assertThat(entry.getTime()).withFailMessage("Expected time %d to be equal to %d for entry %s",
|
||||
entry.getTime(), timestamp, entry.getName()).isEqualTo(timestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void allEntriesUseProvidedTimestamp() throws IOException {
|
||||
this.testJarFile.addClass("A.class", ClassWithMainMethod.class);
|
||||
Repackager repackager = createRepackager(this.testJarFile.getFile(), true);
|
||||
long timestamp = OffsetDateTime.of(2000, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC).toInstant().toEpochMilli();
|
||||
repackager.repackage(this.destination, NO_LIBRARIES, null, FileTime.fromMillis(timestamp));
|
||||
for (ZipArchiveEntry entry : getAllPackagedEntries()) {
|
||||
assertThat(entry.getTime()).isEqualTo(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasLauncherClasses(File file) throws IOException {
|
||||
return hasEntry(file, "org/springframework/boot/")
|
||||
&& hasEntry(file, "org/springframework/boot/loader/JarLauncher.class");
|
||||
|
|
|
|||
Loading…
Reference in New Issue