Search code examples
javamavenmd5sum

Is there any way to get a consistent MD5 Hash from a maven build?


I can run the same maven build 5 times in a row on a group of jar/war files, without any changes to any of them, and yet I get a different MD5 hash on each of the jar/war files each time. I would expect the java compiler to produce the same hash each time. Are there any files that would be affecting the hash that I could exclude to give me the same hash each time? Or is it just that the compiler doesn't compile the same code in the same way each time?

Hash is being generated with the following code:

public static String getHash(File file) throws FileNotFoundException, IOException {
    if(file == null || !file.isFile()) {
        return "";
    }
    FileInputStream in = null;
    try {
        in = new FileInputStream(file);
        byte [] bytes = toByteArray(in);
        return getHash(bytes);
    } catch(Exception e) {
        Logging.log("Unable to get MD5 hash for file: " + ile.getName());
    } finally {
        StreamUtils.close(in);
    }
    return "";
}

public static String getHash(byte[] bytes) {
    MessageDigest digest = getMessageDigest();
    byte[] hash = digest.digest(bytes);
    StringBuilder builder = new StringBuilder();
    for (int val : hash) {
        builder.append(Integer.toHexString(val & 0xff));
    }
    return builder.toString();
}

private static MessageDigest getMessageDigest() {
    try {
        return MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}

Solution

  • A jar or war file is a zip file. A zip file contains zip entries. And zip entries contain metadata about files like their creation and modification time.

    You should pass the content every file of the produced jar/war file to your hash, always in the same order.