You can’t enforce that. There are several unspecified details about the generated class files, like how the byte code of certain source code expressions has to look exactly or the order of members or attributes.
Since there is no requirement to produce exactly the same file in each run, the compiler implementation does not even try. It’s fair to assume that when you execute the same software with exactly the same input (not only the same source code, but also the same options), it will produce the same output, but that does not only require the same compiler version, but also the same JRE.
Unfortunately, there might be different behavior even with the same implementation and input. E.g., there were attempts to randomize the hashing of java.util.HashMap
in some Java?7 implementations and it wouldn’t be surprising if javac
stores certain artifacts in a HashMap
. This does not apply to Java?8, but might apply to the immutable maps to be introduced in Java?9. Whether the compiler will use that feature is not predictable.
So if you found a particular jdk version that reproducibly generates exactly the same byte code, you might be fine with it now, but have to be aware that the next version might not have that property.
It has not been addressed so far that even having the same bytecode does not guaranty to have the same jar
file, as the order of the files within the jar files is unspecified. It might depend on the system specific file iteration order. Further, since jar files are zip files which store timestamps, newly compiled class file do definitely yield a different file, unless you are taking additional measures, e.g. enforce a particular timestamp for all entries.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…