RFR: 8276766: Enable jar and jmod to produce deterministic timestamped content [v12]
John Neffenger
jgneff at openjdk.java.net
Wed Dec 1 01:13:34 UTC 2021
On Tue, 30 Nov 2021 21:56:51 GMT, Andrew Leonard <aleonard at 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 <anleonar at 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 <anleonar at 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
More information about the compiler-dev
mailing list