On Tue, 30 Nov 2021 21:56:51 GMT, Andrew Leonard <aleon...@openjdk.org> wrote:
>> Add a new --source-date <TIMESTAMP> (epoch seconds) option to jar and jmod >> to allow specification of time to use for created/updated jar/jmod entries. >> This then allows the ability to make the content deterministic. >> >> Signed-off-by: Andrew Leonard <anleo...@redhat.com> > > Andrew Leonard has updated the pull request incrementally with one additional > commit since the last revision: > > 8276766: Enable jar and jmod to produce deterministic timestamped content > > Signed-off-by: Andrew Leonard <anleo...@redhat.com> Here is the 32-line Java program that I've been modifying to find problems and solutions: import java.io.FileOutputStream; import java.io.IOException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.temporal.ChronoUnit; import java.util.TimeZone; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class Time { static void writeZipFile(String name, ZipEntry entry) throws IOException { var output = new ZipOutputStream(new FileOutputStream(name)); output.putNextEntry(entry); output.closeEntry(); output.close(); } public static void main(String[] args) throws IOException { var instant = Instant.now().truncatedTo(ChronoUnit.SECONDS); if (args.length > 0) { instant = Instant.parse(args[0]); } System.out.println("Build timestamp = " + instant); var entry = new ZipEntry("Entry"); var local = LocalDateTime.ofInstant(instant, ZoneOffset.UTC); TimeZone.setDefault(TimeZone.getTimeZone("America/Nome")); entry.setTimeLocal(local); writeZipFile("Zipped_in_Nome.zip", entry); TimeZone.setDefault(TimeZone.getTimeZone("Europe/Rome")); entry.setTimeLocal(local); writeZipFile("Zipped_in_Rome.zip", entry); } } For example, first I pick up the timestamp of the last commit in my JavaFX fork: $ export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) $ date --date=@$SOURCE_DATE_EPOCH --iso-8601=seconds --utc 2021-11-22T05:00:22+00:00 $ git log -1 --pretty=%cI 2021-11-21T21:00:22-08:00 Then I can verify that the timestamp in the archive is unaffected by the default time zone of the JVM: $ java Time 2021-11-21T21:00:22-08:00 Build timestamp = 2021-11-22T05:00:22Z $ for f in *.zip; do zipinfo -v $f | grep -e Archive -e modified; done Archive: Zipped_in_Nome.zip file last modified on (DOS date/time): 2021 Nov 22 05:00:22 Archive: Zipped_in_Rome.zip file last modified on (DOS date/time): 2021 Nov 22 05:00:22 Even when I create the ISO 8601 date and time string on a system in a different time zone than the two simulated build machines in Nome and Rome, it still works: $ java Time 2021-11-22T08:00:22+03:00 Build timestamp = 2021-11-22T05:00:22Z $ for f in *.zip; do zipinfo -v $f | grep -e Archive -e modified; done Archive: Zipped_in_Nome.zip file last modified on (DOS date/time): 2021 Nov 22 05:00:22 Archive: Zipped_in_Rome.zip file last modified on (DOS date/time): 2021 Nov 22 05:00:22 But it all falls apart when we venture outside the permitted DOS date and time range: $ java Time 1975-11-22T05:00:22+00:00 Build timestamp = 1975-11-22T05:00:22Z $ for f in *.zip; do zipinfo -v $f | grep -e Archive -e modified; done Archive: Zipped_in_Nome.zip file last modified on (DOS date/time): 1980 Jan 1 00:00:00 file last modified on (UT extra field modtime): 1975 Nov 22 08:00:22 local file last modified on (UT extra field modtime): 1975 Nov 22 16:00:22 UTC Archive: Zipped_in_Rome.zip file last modified on (DOS date/time): 1980 Jan 1 00:00:00 file last modified on (UT extra field modtime): 1975 Nov 21 20:00:22 local file last modified on (UT extra field modtime): 1975 Nov 22 04:00:22 UTC ------------- PR: https://git.openjdk.java.net/jdk/pull/6481