Java › Build Tools: Maven & Gradle

How would you configure a Maven or Gradle build to produce a reproducible build (bit-for-bit identical output given the same source), and why does this matter for supply chain security?

Advanced

Answer

Reproducible builds require eliminating all non-deterministic elements from the build process: fixing file timestamps in the packaged JAR (Maven's <project.build.outputTimestamp> property, tied to a specific commit's timestamp rather than build-time), ensuring consistent file ordering within the archive, pinning exact dependency versions (avoiding version ranges), and using a consistent JDK version -- reproducibility matters for supply chain security because it lets independent third parties verify that a published artifact genuinely corresponds to its claimed source code, detecting any tampering or compromised build infrastructure that might otherwise inject malicious code undetected.
<!-- pom.xml -- enabling reproducible builds -->
<properties>
    <project.build.outputTimestamp>2024-01-15T10:00:00Z</project.build.outputTimestamp>
</properties>

# Verify reproducibility by building twice and comparing checksums
mvn clean package
sha256sum target/myapp.jar > build1.sha256
mvn clean package
sha256sum target/myapp.jar > build2.sha256
diff build1.sha256 build2.sha256  # should be identical
Real-world example An open-source project publishing artifacts to Maven Central configures reproducible builds so that security-conscious downstream consumers can independently rebuild from the published source and cryptographically verify the published JAR matches exactly, providing evidence the artifact wasn't tampered with during the publishing process.

Common follow-ups: What specific non-determinism sources (beyond timestamps) commonly break build reproducibility?;How do supply chain security frameworks like SLSA leverage reproducible builds as one verification layer?