When building a project with Maven, the generated binary artifact would typically differ from one build to another, even if nothing has changed in the project. Systems relying on binary fingerprints (e.g. checks on MD5 hash) would detect different artifacts although the source is exactly the same. The change in the binary Jar files results from different timestamps, possibly different ordering of the entries, among other reasons. One way to solve this is by “fixing” the timestamp of the Jar entries (to some constant value), sorting the entries of the manifest, etc.
The jar-timestamp-normalize-maven-plugin is a Maven plugin which provides this capability. It consists of a single goal called
normalize which can be bound to the
package lifecycle phase and configured in the project’s POM:
<plugins> <plugin> <groupId>com.github.manouti</groupId> <artifactId>jar-timestamp-normalize-maven-plugin</artifactId> <version>1.0-SNAPSHOT</version> <executions> <execution> <id>jar-normalize</id> <goals> <goal>normalize</goal> </goals> <phase>package</phase> </execution> </executions> </plugin> </plugins>
Normalization mainly consists of the following steps:
- Alphabetically sort all files and directories in the Jar.
- Setting the last modified time of all Jar entries to a specific timestamp (default value is
1970-01-01 00:00:00AMbut can be changed by passing
-Dtimestampas a system property).
- Reordering (alphabetically) of attributes in the manifest except for
Manifest-Versionwhich always comes first.
- Removing comments from the
pom.propertiesfile which contain a timestamp that causes the Jar to differ from one build to another.
Once invoked, the goal will generate the output file next to the original artifact (named
artifactId-version-normalized.jar), i.e. in the
List of configuration parameters:
||Where to store the output artifact, defaults to the project output directory.|
||Fixed timestamp for artifact entries, defaults to
||Artifact name to be used in the output file name, default to the project’s artifactId.|
||Classifier to be used in the output file name, defaults to