Skip to content

Reproducibility notes

Martin Paljak edited this page Aug 25, 2026 · 1 revision

Important

Set TZ=UTC and SOURCE_DATE_EPOCH. Without them Java-Card-CAP-Creation-Time carries the wall clock and nothing below holds.

The Load File Data Block depends on the sources and the target JavaCard version. The .cap container around it also depends on the JDK.

Load File Data Block

The JDK and the jckit release do not change it. Every jckit that supports a target gives the same LFDBH for it:

Target Same LFDBH with jckit
2.2.2 v3.0.1, v3.0.4, v3.0.5u4
3.0.4 v3.0.4, v3.0.5u4, v3.1.0, v24.0, v24.1, v25.0, v25.1, v26.0
3.0.5 v3.0.5u4, v26.0

targetsdk="sdks/jc304_kit" and targetsdk="3.0.4" give the same CAP. With a multi-target jckit, a path in targetsdk selects only the version of the SDK it points to.

Container

Across JDKs, all CAP components, APPLET-INF/applet.xml and META-INF/javacard.xml are byte-identical. Two entries differ:

Entry Differs in JDK groups
META-INF/MANIFEST.MF attribute order, line folding at 70 or 72 bytes {8}, {11, 17, 21, 25}
APPLET-INF/classes/**.class javac constant pool numbering {8, 11}, {17, 21, 25}

strip="true" drops the class files, which leaves only the manifest to differ:

cap Identical .cap from JDK
default {8}, {11}, {17, 21, 25}
strip="true" {8}, {11, 17, 21, 25}

Measuring

TZ=UTC SOURCE_DATE_EPOCH=1700000000 JAVA_HOME=/path/to/jdk ant ...
java -jar ant-javacard.jar built.cap        # LFDBH as SHA-256
shasum -a 256 built.cap                     # whole container

%h in the default output template is the LFDBH prefix. %J gives byte-identical CAP files from JDK 17, 21 and 25 different names.

Unzip two CAP files and compare per-entry hashes to find the differing entries.

Measured 2026-09-08 with src/testapplets/empty on Zulu 8, 11, 17, 21, 25.

Clone this wiki locally