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:

  1. Upgrade your plugins to reproducible versions, particularly maven-jar-plugin, maven-source-plugin, and maven-assembly-plugin to version 3.2.0 minimum.
  2. Enable Reproducible Builds mode for plugins, by adding property to the project's pom.xml:

You have the basics configured. The output should be reproducible now.

How to test my Maven build reproducibility?

Using maven-artifact-plugin's compare goal, you can check that the second build of your project produce the same output than an initial build:

  1. build and install your project: mvn clean install (don't hesitate to customize arguments to better match your project)
  2. rebuild (verify only, without installing) and check against the previous install: mvn clean verify artifact:compare

How to fix my Maven build reproducibility?

If something is still not reproducible after initial setup:

  1. 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.
  2. Find the plugin that generated this output.
  3. 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.