I was attempting to compare the results of this: (in ant)
<javac
target="1.5"
source="1.5"
deprecation="on"
fork="yes"
optimize="true"
debug="true"
debuglevel="lines,vars,source">
<classpath>
<fileset dir="${project.basedir}/../lib">
<include name="**/*.jar" />
<include name="**/*.zip" />
</fileset>
</classpath>
</javac>
...against this: (in maven)
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<target>1.5</target>
<source>1.5</source>
<debug>true</debug>
<debuglevel>lines,vars,source</debuglevel>
<showDeprecation>true</showDeprecation>
<optimize>true</optimize>
<fork>true</fork>
<includes>
...
</includes>
</configuration>
</execution>
</executions>
</plugin>
...only to discover that 2 of the resulting class files have slightly different checksums, while the rest are identical. I consider multi-threading to have played a part, but the checksums produced for either option appear to be consistent upon repeated attempts. What can possibly account for this result?
Update:
I have examined one set of the files with different checksums using javap -verbose
and noticed the only difference being:
const #16 = class #108; // java/lang/Exception
const #17 = Method #102.#109; // java/io/Writer.close:()V
const #18 = Method #7.#109; // java/io/FileWriter.close:()V
as opposed to:
const #16 = Method #102.#108; // java/io/Writer.close:()V
const #17 = Method #7.#108; // java/io/FileWriter.close:()V
const #18 = class #109; // java/lang/Exception
as you showed, the difference is in the generated constant pool, which is really a non-issue, but troubling as you would expect the same output with the same compiler and options. i would bet that the compiler is called with the java files in different order between the two situations, and the order of compilation is affecting the result.
I'm using javac compiler and I've found it produces different resulting binary .class files depending on the order of the source files passed as parameter. Between maven and ant I found differences. The order of the files were not the same.
Anyway, between the 2 compilations there were differences. I've disassembled the code and I found the javac (optimizer?) was removing the deprecated java jsr/ret assembly instructions from one of the compilations.
I don't know if this behaviour it's the result of "implicit" compilation: http://docs.oracle.com/javase/1.5.0/docs/tooldocs/solaris/javac.html#searching