Reproducibility for Java -> technical details
Roland Clobus
rclobus at rclobus.nl
Tue Nov 12 16:55:07 UTC 2024
Hello Magnus,
Thanks for your interest.
On 12/11/2024 15:33, Magnus Ihse Bursie wrote:
> I'm working with the Build Group on OpenJDK. We have tried to make the
> build of the JDK to be reproducible, as a long-term project spanning
> several years. This has, at time, included changes to Java itself (like
> a way to make .properties files without a timestamp comment).
>
> The builds we produce in the OpenJDK project, on Linux, is fully
> reproducible as far as I am aware. I must admit I did not follow all
> links in your mail to fully understand the problem you are seeing, but
> it seems that the gist is "the problem is in our distribution, but the
> fix must lie within Java itself".
Building Java (the binary program that executes Java code) is
reproducible (for amd64 on Debian) [5], but running programs written in
Java might not be, as is the case here for the Debian
ca-certificates-java package.
> If indeed a fix is needed in Java to enable reproducibility, I can
> probably help to try and drive such a change. However, I need to
> understand the problem better first, to determine if I agree that a fix
> in the JDK itself is in place.
>
> Can you indulge me by writing down a clear problem statement in a mail
> to this list, on why reproducibility fails in your build, what change
> you want to make in the JDK, and why you think this will solve the
> problem? I'm sorry to put the burden on you, but the Build Group is
> unfortunately understaffed and I do not have much time to work with
> "non-essential" stuff (like reproducibility) as I'd like.
The package ca-certificates-java is a tool that (re)generates
/etc/ssl/cert/java/cacerts. It uses java.security.KeyStore [1], which in
turn uses sun.security.provider.JavaKeyStore [2], which at lines 290,
353 and 394 calls 'new Date()'.
The default constructor of java.util.Date [3] uses
System.currentTimeMillis().
System.currentTimeMillis() is marked as @IntrinsicCandidate (as well as
the more precise System.nanoTime().
My proposed change would be:
* At startup of Java, check if SOURCE_DATE_EPOCH is set. If so, create a
Clock.fixed with the timestamp from SOURCE_DATE_EPOCH
* In java.util.Date replace System.currentTimeMillis() with
Clock.getInstance().currentTimeMillis() (as suggested at [4] and other
sources)
* Something similar might be required for System.nanoTime, but I didn't
need that for this specific case.
It should be noted that regular user _will not_ and _should not_ set
SOURCE_DATE_EPOCH [6]. That environment variable it typically used for
rebuilds.
With kind regards,
Roland Clobus
[1]
https://sources.debian.org/src/ca-certificates-java/20240118/src/main/java/org/debian/security/KeyStoreHandler.java/#L43
[2]
https://sources.debian.org/src/openjdk-23/23.0.1+11-1/src/java.base/share/classes/sun/security/provider/JavaKeyStore.java/?hl=381#L381
[3]
https://sources.debian.org/src/openjdk-23/23.0.1+11-1/src/java.base/share/classes/java/util/Date.java/?hl=128#L128
[4]
https://stackoverflow.com/questions/2001671/override-java-system-currenttimemillis-for-testing-time-sensitive-code
[5]
https://tests.reproducible-builds.org/debian/rb-pkg/unstable/amd64/openjdk-23.html
[6] https://reproducible-builds.org/docs/source-date-epoch/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.reproducible-builds.org/pipermail/rb-general/attachments/20241112/d8301eb0/attachment.sig>
More information about the rb-general
mailing list