On Mon, 22 Nov 2021 02:36:00 GMT, John Neffenger <jgn...@openjdk.org> wrote:
>> Add a new --source-date <TIMESTAMP> (epoch milliseconds) 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> > > Thank you for this timely pull request, Andrew! I need this pull request and > also #6395 to [enable reproducible builds in > JavaFX](https://github.com/openjdk/jfx/pull/446). I drove myself crazy this > weekend with time zones, and if I understand your proposed changes correctly, > it looks as if you're hitting the same problems as I did: > > 1. The [`SOURCE_DATE_EPOCH` environment > variable](https://reproducible-builds.org/specs/source-date-epoch/) is > defined as the number of **seconds** since the epoch of 1970-01-01T00:00:00Z, > but the new command option is defined as the number of milliseconds. That > makes it difficult to set `--source-date=$SOURCE_DATE_EPOCH` on the command > line. > > 2. Calling the method `ZipEntry.setTime(long)` will not allow for > reproducible builds when the builds run in different time zones. > > For the second problem, run the included Java Time program as shown below: > > > $ javac Time.java > $ echo $SOURCE_DATE_EPOCH > 1637085342 > $ date --date="@$SOURCE_DATE_EPOCH" > Tue 16 Nov 2021 09:55:42 AM PST > $ java Time > Build timestamp = 2021-11-16T17:55:42Z > $ for f in *.zip; do zipinfo -v $f | grep -e Archive -e modified; done > Archive: FailsInNome.zip > file last modified on (DOS date/time): 2021 Nov 16 08:55:42 > Archive: FailsInRome.zip > file last modified on (DOS date/time): 2021 Nov 16 18:55:42 > Archive: WorksInNome.zip > file last modified on (DOS date/time): 2021 Nov 16 17:55:42 > Archive: WorksInRome.zip > file last modified on (DOS date/time): 2021 Nov 16 17:55:42 > > > 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); > var sourceDateEpoch = System.getenv("SOURCE_DATE_EPOCH"); > if (sourceDateEpoch != null) { > long seconds = Long.parseLong(sourceDateEpoch); > instant = Instant.ofEpochSecond(seconds); > } > System.out.println("Build timestamp = " + instant); > > var entry = new ZipEntry("Entry"); > > long newTime = 1000 * instant.getEpochSecond(); > TimeZone.setDefault(TimeZone.getTimeZone("America/Nome")); > entry.setTime(newTime); > writeZipFile("FailsInNome.zip", entry); > TimeZone.setDefault(TimeZone.getTimeZone("Europe/Rome")); > entry.setTime(newTime); > writeZipFile("FailsInRome.zip", entry); > > var dosTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC); > TimeZone.setDefault(TimeZone.getTimeZone("America/Nome")); > entry.setTimeLocal(dosTime); > writeZipFile("WorksInNome.zip", entry); > TimeZone.setDefault(TimeZone.getTimeZone("Europe/Rome")); > entry.setTimeLocal(dosTime); > writeZipFile("WorksInRome.zip", entry); > } > } @jgneff Hi John, thanks for the comment, I hadn't realized that aspect, but sort of obvious when you look at the ZIP spec for dostime, which has no timezone info. So with this in mind the --source-date=<timestamp> option I am looking to add for jar/jmod, will need to state the timestamp is an "Epoch timestamp", ie. seconds since Jan1 1970 in UTC, and that as such the jar/jmod dostime will represent UTC "local time", akin to the EPOCH_SOURCE_DATE spec: https://reproducible-builds.org/specs/source-date-epoch/ I will update my PR to to use this. thanks ------------- PR: https://git.openjdk.java.net/jdk/pull/6481