rjzii
rjzii

Reputation: 14543

Is the class file generated by javac always the same?

Currently we are in the process of re-scripting all of our build system for a large project (around 2000 source files) and there has been talk of doing a binary comparison on the files to ensure that everything is correct which leads to the following question: Is the output of javac guaranteed to be same across compilations or could it be subject to change?

Another question implied that the constant pool could have a different order, but assuming we are able to control for the order of the files going into the javac call is there still a potential for differences? We are using Ant and Maven as part of the build if that may influence things as well.

Upvotes: 6

Views: 589

Answers (3)

Hot Licks
Hot Licks

Reputation: 47729

The only way to assure equivalence is to get one of the several class file parsers, parse the files, then do the heavy work of figuring out differences due to constant pool order changes, etc. The main problem is that reordering the constant pool will change numeric values that reference the constants, some of which are in table elements, some of which are in bytecodes. Doable, but definitely non-trivial, and probably not practical unless you already have most of the framework in place for some other reason (such as bytecode modification).

Upvotes: 1

ruakh
ruakh

Reputation: 183321

The bytecode is absolutely not guaranteed to be the same; for one thing, compilers are allowed to perform optimizations that don't affect any guaranteed behaviors. The Java Language Specification even mentions, in a few places, optimizations that a compiler might perform; for example, of the string concatenation operator +, it notes that:

An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.

[link]

Upvotes: 5

romacafe
romacafe

Reputation: 3128

I am not an expert on the compiler, but I tend to believe the other answers saying that binary comparison is not 100% reliable.

I'd consider another alternative: You should be able to inspect the artifacts your build system creates (.jars & .wars, etc.) and ensure that each have the expected contents, and even that the size of each file is within a fairly tight tolerance.

If your build script is generating source and compiling it, then you should be able to do comparisons against the generated source, which I expect would be 100% stable from build to build. (Or at least predictable).

Hope this helps!

Upvotes: 0

Related Questions