import com.google.common.io.ByteStreams import org.gradle.api.* import java.util.zip.ZipEntry import java.util.zip.ZipFile import java.util.zip.ZipOutputStream import java.nio.file.Files import java.nio.file.attribute.FileTime import java.nio.file.Paths import java.nio.file.StandardCopyOption // Custom Gradle plugin that attempts to make the resulting jar file deterministic. // Ie. same contract definition should result when compiled in same jar file. // This is done by removing date time stamps from the files inside the jar. class CanonicalizerPlugin implements Plugin { void apply(Project project) { project.getTasks().getByName('jar').doLast() { def zipPath = (String) project.jar.archivePath def destPath = Files.createTempFile("processzip", null) def zeroTime = FileTime.fromMillis(0) def input = new ZipFile(zipPath) def entries = input.entries().toList().sort { it.name } def output = new ZipOutputStream(new FileOutputStream(destPath.toFile())) output.setMethod(ZipOutputStream.DEFLATED) entries.each { def newEntry = new ZipEntry( it.name ) newEntry.setLastModifiedTime(zeroTime) newEntry.setCreationTime(zeroTime) newEntry.compressedSize = -1 newEntry.size = it.size newEntry.crc = it.crc output.putNextEntry(newEntry) ByteStreams.copy(input.getInputStream(it), output) output.closeEntry() } output.close() input.close() Files.move(destPath, Paths.get(zipPath), StandardCopyOption.REPLACE_EXISTING) } } }