Is the class file created by javac immutable?

We are currently in the process of re-scripting our entire build system for a large project (about 2000 source files), and we talked about doing binary file comparisons to make sure everything is correct, which leads to the following question: Is javac output guaranteed the same for compilation or can it be changed?

Another question implied that the constant pool could have a different order, but provided that we can control the order of the files included in the javac call, is there any potential for differences? We use Ant and Maven as part of the build if this can affect things.

+6
source share
3 answers

The byte code is absolutely not guaranteed to remain unchanged; on the one hand, compilers are allowed to perform optimizations that do not affect any guaranteed behavior. The Java language specification even mentions in several places the optimization that the compiler can do; for example, the string concatenation operator + , he notes that:

An implementation can choose to perform conversion and concatenation in one step to avoid creating and then dropping the intermediate String object. To improve string re-concatenation performance, the Java compiler can use the StringBuffer class or a similar method to reduce the number of intermediate String objects created when evaluating an expression.

[ link ]

+3
source

I am not an expert in the compiler, but I am inclined to believe that other answers suggest that binary comparison is not 100% more reliable.

I would consider another alternative: you should be able to check artifacts created by your build system (.jars and .wars, etc.), and ensure that everyone has the expected content, and even the size of each file, within a fairly tight tolerance .

If your build script generates the source code and compiles it, then you should be able to make comparisons with the generated source, which, as I expected, will be 100% stable from build to build. (Or at least predictable).

Hope this helps!

0
source

The only way to guarantee equivalence is to get one of several parsers of class files, parse the files, then do the hard work of figuring out the differences due to constant changes in the order of the pool, etc. The main problem is that pool constant reordering will change numerical values ​​that refer to constants, some of which are in table elements, some of which are in byte codes. A feature, but definitely non-trivial and probably not practical, if you already have most of the framework for some other reason (for example, bytecode modification).

0
source

Source: https://habr.com/ru/post/911953/


All Articles