2012-03-29 4 views
6

В настоящее время мы находимся в процессе повторной скриптации всей нашей системы сборки для большого проекта (около 2000 исходных файлов), и там говорилось о выполнении двоичного сравнения файлов, чтобы убедиться, что все правильно, что приводит к следующий вопрос: Является ли вывод javac гарантией того, что он будет одинаковым для компиляций, или он может быть изменен?Является ли файл классов, созданный javac, неизменным?

Another question предполагает, что константа бассейн может иметь различный порядок, но при условии, что мы в состоянии контролировать для заказа файлов, идущих в javac вызова есть еще потенциал для различия? Мы используем Ant и Maven как часть сборки, если это может повлиять и на вещи.

+2

Не гарантируется. На практике это, вероятно, будет идентичным, если вы используете идентичную структуру JAR для компилятора и компиляции, но даже незначительные изменения в порядке JAR и т. Д. Могут нарушить работу applecart. –

+0

Разве ваши тесты не гарантировали бы * функциональную * эквивалентность, что вас действительно беспокоит? В любом случае, почему бы просто не попробовать и не посмотреть, что происходит? Если вы обнаружите, что материал был переупорядочен, вам придется пройти и выполнить анализ байтового кода, чтобы убедиться, что они эквивалентны в байтах. –

+0

Действительно интересно, зачем вам нужно бинарное сравнение построенных классов? –

ответ

3

Байт-код абсолютно не гарантированно будет таким же; с одной стороны, компиляторам разрешено выполнять оптимизации, которые не влияют на какое-либо гарантированное поведение. Спецификация языка Java даже упоминает в нескольких местах оптимизацию, которую может выполнить компилятор; например, оператора конкатенации +, он отмечает, что:

Реализация может выбрать, чтобы выполнять преобразование и конкатенацию в один шаг, чтобы избежать создания и удаления промежуточного String объекта. Чтобы повысить производительность повторной конкатенации строк, компилятор Java может использовать класс StringBuffer или подобный метод для уменьшения количества промежуточных объектов String, которые создаются путем оценки выражения.

[link]

0

Я не специалист по компилятору, но я склонен полагать, что другие ответы говорят о том, что бинарное сравнение не на 100% надежное.

Я бы рассмотрел еще одну альтернативу: вы должны иметь возможность проверять артефакты, создаваемые вашей системой сборки (.jars & .wars и т. Д.) И гарантировать, что каждый из них имеет ожидаемое содержимое и даже размер каждого файла находится в довольно жесткой толерантности.

Если ваш скрипт сборки генерирует исходный код и компилирует его, то вы должны иметь возможность делать сравнения с сгенерированным источником, который, как я ожидаю, будет быть на 100% стабильным от сборки до сборки. (Или, по крайней мере, предсказуемым).

Надеюсь, это поможет!

0

Единственный способ убедиться в эквивалентности, чтобы получить один из нескольких парсеров файлов класса, разбора файлов, а затем делать тяжелую работу выяснить различия, связанные с постоянным изменением порядка бассейна, и т. д. Основная проблема заключается в том, что переупорядочение пула констант будет изменять числовые значения, которые ссылаются на константы, некоторые из которых находятся в элементах таблицы, некоторые из которых относятся к байт-кодам. Возможность, но определенно нетривиальная и, вероятно, не практичная, если у вас уже есть большая часть фреймворка по какой-либо другой причине (например, модификация байт-кода).

Смежные вопросы