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