We just discovered when we started using lambda expressions in JDK 8 that .class files can vary from compile to compile, particularly from machine to machine where the environments may differ. We haven’t seen this before. We’ve come to expect that .class files don’t change unless the java source changes, however the java compiler offers no such contract in general. It only places a guarantee on runtime behavior, and makes no commitment to create identical byte code for any given source. In particular, when java source files are compiled (via the java-compiler-args.txt in the case of gradle) with the source files listed in a different order, you may very well end up with synthetic methods and attributes in a different order with different numeric suffixes.
Although this bug, https://bugs.openjdk.java.net/browse/JDK-8067422, fixed in JDK9 (but not currently in JDK8) mentions the case above, this is but one example. It would be good if the gradle java compile would sort the source files to reduce (but will never be able to totally eliminate) the problem.
I patched my copy of gradle 2.5 and verified that this leads to stability in the class files using jDK8. The patch I made is to org.gradle.api.internal.tasks.compile.JavaCompilerArgumentsBuilder:
private void addSourceFiles() {
if (!includeSourceFiles) {
return;
}
// putting the .java files in sorted order helps ensure that the java compiler doesn't
// introduce changes in repeated compiles .class files
// jim.gish@oracle.com - Aug. 27, 2015
List<File> sortedFiles = new ArrayList<File>(spec.getSource().getFiles());
Collections.sort(sortedFiles);
for (File file : sortedFiles) {
args.add(file.getPath());
}
}
Please make this or equivalent change to the next version of gradle possible.
Thanks,
Jim