Set timestamps of nested jars
Update JarWriter to set the entry timestamp for nested jars. The timestamp is set to same time as the first (non directory) entry in the nested jar. This change should make it easier to created layered docker images. Fixes gh-2807
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2015 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.
|
||||
@@ -162,6 +162,7 @@ public class JarWriter {
|
||||
throws IOException {
|
||||
File file = library.getFile();
|
||||
JarEntry entry = new JarEntry(destination + library.getName());
|
||||
entry.setTime(getNestedLibraryTime(file));
|
||||
if (library.isUnpackRequired()) {
|
||||
entry.setComment("UNPACK:" + FileUtils.sha1Hash(file));
|
||||
}
|
||||
@@ -169,6 +170,28 @@ public class JarWriter {
|
||||
writeEntry(entry, new InputStreamEntryWriter(new FileInputStream(file), true));
|
||||
}
|
||||
|
||||
private long getNestedLibraryTime(File file) {
|
||||
try {
|
||||
JarFile jarFile = new JarFile(file);
|
||||
try {
|
||||
Enumeration<JarEntry> entries = jarFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
if (!entry.isDirectory()) {
|
||||
return entry.getTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
jarFile.close();
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Ignore and just use the source file timestamp
|
||||
}
|
||||
return file.lastModified();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the required spring-boot-loader classes to the JAR.
|
||||
* @throws IOException
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.util.Calendar;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
@@ -58,6 +59,17 @@ public class RepackagerTests {
|
||||
}
|
||||
};
|
||||
|
||||
private static final long JAN_1_1980;
|
||||
private static final long JAN_1_1985;
|
||||
static {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(1980, 0, 1, 0, 0, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
JAN_1_1980 = calendar.getTime().getTime();
|
||||
calendar.set(Calendar.YEAR, 1985);
|
||||
JAN_1_1985 = calendar.getTime().getTime();
|
||||
}
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
@@ -275,7 +287,7 @@ public class RepackagerTests {
|
||||
@Test
|
||||
public void libraries() throws Exception {
|
||||
TestJarFile libJar = new TestJarFile(this.temporaryFolder);
|
||||
libJar.addClass("a/b/C.class", ClassWithoutMainMethod.class);
|
||||
libJar.addClass("a/b/C.class", ClassWithoutMainMethod.class, JAN_1_1985);
|
||||
final File libJarFile = libJar.getFile();
|
||||
final File libJarFileToUnpack = libJar.getFile();
|
||||
final File libNonJarFile = this.temporaryFolder.newFile();
|
||||
@@ -284,6 +296,7 @@ public class RepackagerTests {
|
||||
this.testJarFile.addFile("lib/" + libJarFileToUnpack.getName(),
|
||||
libJarFileToUnpack);
|
||||
File file = this.testJarFile.getFile();
|
||||
libJarFile.setLastModified(JAN_1_1980);
|
||||
Repackager repackager = new Repackager(file);
|
||||
repackager.repackage(new Libraries() {
|
||||
@Override
|
||||
@@ -297,7 +310,9 @@ public class RepackagerTests {
|
||||
assertThat(hasEntry(file, "lib/" + libJarFile.getName()), equalTo(true));
|
||||
assertThat(hasEntry(file, "lib/" + libJarFileToUnpack.getName()), equalTo(true));
|
||||
assertThat(hasEntry(file, "lib/" + libNonJarFile.getName()), equalTo(false));
|
||||
JarEntry entry = getEntry(file, "lib/" + libJarFileToUnpack.getName());
|
||||
JarEntry entry = getEntry(file, "lib/" + libJarFile.getName());
|
||||
assertThat(entry.getTime(), equalTo(JAN_1_1985));
|
||||
entry = getEntry(file, "lib/" + libJarFileToUnpack.getName());
|
||||
assertThat(entry.getComment(), startsWith("UNPACK:"));
|
||||
assertThat(entry.getComment().length(), equalTo(47));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2015 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.
|
||||
@@ -46,11 +46,19 @@ public class TestJarFile {
|
||||
}
|
||||
|
||||
public void addClass(String filename, Class<?> classToCopy) throws IOException {
|
||||
addClass(filename, classToCopy, null);
|
||||
}
|
||||
|
||||
public void addClass(String filename, Class<?> classToCopy, Long time)
|
||||
throws IOException {
|
||||
File file = getFilePath(filename);
|
||||
file.getParentFile().mkdirs();
|
||||
InputStream inputStream = getClass().getResourceAsStream(
|
||||
"/" + classToCopy.getName().replace(".", "/") + ".class");
|
||||
copyToFile(inputStream, file);
|
||||
if (time != null) {
|
||||
file.setLastModified(time);
|
||||
}
|
||||
}
|
||||
|
||||
public void addFile(String filename, File fileToCopy) throws IOException {
|
||||
|
||||
Reference in New Issue
Block a user