Configuring for Reproducible Builds
What are Reproducible Builds?
Reproducible builds are a set of software development practices that create an independently-verifiable path from source to binary code. A build is reproducible if given the same source code, build environment and build instructions, any party can recreate bit-by-bit identical copies of all specified artifacts.
Reproducible Central lists projects releases that have been checked as reproducible by rebuilding independently from the reference build published in Central Repository.
How do I configure my Maven build?
There is no Maven version prerequisite. Everything happens at plugin level:
- Upgrade your plugins to reproducible versions: to easily detect required upgrades, run
mvn artifact:check-buildplan
- Enable Reproducible Builds mode for plugins, by adding
project.build.outputTimestamp
property to the project'spom.xml
:<properties> <project.build.outputTimestamp>2023-01-01T00:00:00Z</project.build.outputTimestamp> </properties>
Notice: starting with Maven 4.0.0-beta-5, Reproducible Builds mode will be active by default (see MNG-8258), without modifying project's pom.xml
. Setting a value in your pom.xml
will only be useful if you want to override the inherited value.
You have the basics configured. The output should be mostly reproducible now.
How to test my Maven build reproducibility?
Using maven-artifact-plugin
's compare
goal, you can easily check that the second build of your project produce the same output than an initial build:
- build and
install
your project (don't hesitate to customize arguments to better match your project):mvn clean install
- rebuild (
verify
only, without installing) and check against the previous install:mvn clean verify artifact:compare
Notice that this local test does NOT really prove that your build is yet reproducible by a third party, because it may still suffer from environment leaks (username, current directory, ...). But it is easy to do, and prevents basic non-reproducible issues like timestamps. Really checking reproducibility requires to rebuild from a completely different setup: this is harder to do, even if containers may ease the task.
How to fix my Maven build reproducibility?
If something is still not reproducible after initial setup and automatic check from artifact:check-buildplan
:
- Use diffoscope to find the unstable output between builds. The
artifact:buildinfo
goal proposes a command with path to files: just copy/paste to launch. - Find the plugin that generated this output.
- Check if a reproducible version of the plugin is available. If not, please open an issue to help plugin maintainers improving Reproducible Builds support at every plugin level.
More Details
Reproducible Builds for Maven:
- Require no version ranges in dependencies,
- Generally give different results on Windows and Unix because of different newlines. (carriage return linefeed on Windows, linefeed on Unixes)
- Generally depend on the major version of the JDK used to compile. (Even with source/target defined, each major JDK version changes the generated bytecode)
For detailed explanations, see Maven "Reproducible/Verifiable Builds" Wiki page.
FAQ
- Q. Can the
project.build.outputTimestamp
property inpom.xml
be updated automatically at release time?A. Yes.
Details depend on your release process tooling:
- if you use maven-release-plugin, you'll need version 3.0.0-M1 or later: it will automatically update the timestamp value in
pom.xml
during the release in the same commit that updates version, - if you have a custom release process tooling, you'll need to add the feature to your release tooling. Notice that if you're using
versions-maven-plugin
in custom release scripts, starting with release 2.9.0,versions:set
goal updates the property. - instead of explicitly writing a timestamp in their
pom.xml
, some people tend to prefer using last Git commit timestamp, like${git.commit.time}
from git-commit-id-maven-plugin (with<dateFormatTimeZone>UTC</dateFormatTimeZone>
to be independent from user's timezone).
- if you use maven-release-plugin, you'll need version 3.0.0-M1 or later: it will automatically update the timestamp value in
Don't hesitate to share your questions or solutions on user mailing-list.
- Q. Which additional plugins need to be updated for Reproducible Builds?
A. See the list of required upgrades