Декомпиляция файлов классов java и сравнение с svn

У нас есть обычные файлы Java, находящиеся в SVN. Мы внесли некоторые изменения в эти файлы, но бывает так, что эти файлы теряются (их нет в SVN). Но у нас есть файлы классов, созданные с использованием недавно измененных файлов.

Можем ли мы использовать файлы классов, декомпилировать их и сравнить с SVN. Как это сделать проще всего?

Там около 400 измененных файлов. Поэтому сравнивать по отдельности нецелесообразно.

Я ищу любой инструмент или скрипты.

Также есть ли какой-нибудь декомпилятор, который бы декомпилировал всю папку за один раз?

Спасибо


person Vinoth Kumar C M    schedule 06.06.2011    source источник
comment
Это, вероятно, будет сложно, поскольку декомпиляция всегда является своего рода догадкой. Это не приведет к созданию исходного исходного кода, а только к исходному коду, который будет скомпилирован с тем же байт-кодом. Таким образом, вы получите множество ложных различий. Вероятно, это нормально, если вы выполняете все вручную и имеете приблизительное представление об изменениях, но сделать это автоматически будет настоящим испытанием.   -  person Andrzej Doyle    schedule 06.06.2011
comment
Если вы использовали Eclipse для разработки, скорее всего, они еще не потеряны. Вы можете попробовать восстановить из локальной истории.   -  person adarshr    schedule 06.06.2011
comment
Я не говорю об автоматическом выполнении, но, по крайней мере, он должен сравнивать и говорить, какие файлы отличаются.   -  person Vinoth Kumar C M    schedule 06.06.2011


Ответы (6)


Для декомпиляции используйте JAD, наиболее часто используемый инструмент. Хотя сравнивать немного сложно. Я бы предложил следующий сценарий:

  1. Возьмите последний исходный код из SVN
  2. Построить это
  3. Декомпилируйте его (!)
  4. Возьмите ваши скомпилированные классы, которые включают некоторые модификации, но у вас нет исходников.
  5. Декомпилировать их тоже
  6. Сравните оба каталога декомпилированных исходников

Зачем компилировать и декомпилировать исходные коды? Потому что JAD дает довольно хорошие результаты, но он никогда не будет генерировать в точности те же источники, которые использовались. Поэтому, если вы хотите избежать головной боли при сравнении исходных и декомпилированных источников (и быстро выявить фактические различия), вам нужно сравнить два вывода JAD, а не исходный код и синтетический вывод JAD.

Я надеюсь, что наличие двух структур каталогов для сравнения не будет проблемой для вас. Вы можете использовать Total Commander в Windows или различные утилиты/скрипты в Linux, например:

$ diff -r dir1 dir2
person Tomasz Nurkiewicz    schedule 06.06.2011
comment
+1: JAD не будет восстанавливать комментарии, исходный межстрочный интервал, использование import * vs import каждого класса, имена локальных переменных, аннотации сохранения SOURCE и многое другое, потому что этой информации нет в классе. - person Peter Lawrey; 06.06.2011

jad может декомпилировать целую папку, но результат зависит от нескольких факторов. Во-первых, JAD хорошо поддерживает только Java 4. Java 5 и более поздние версии будут содержать нечетные фрагменты байтового кода, которые JAD не понимает.

Если код скомпилирован с отладочными символами, вы можете изменить номера строк (это может сделать плагин jadclipse) но сам JAD не может этого сделать.

Если вы скомпилировали код с помощью -g:source, то файлы классов содержат полный исходный код. На первый взгляд, я не знаю, как это сделать, но такие инструменты, как javap (поставляется с JDK) или ASM должен позволить вам получить его.

person Aaron Digulla    schedule 06.06.2011

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

person THelper    schedule 06.06.2011

Я использовал приведенную ниже команду (декомпилятор jad), чтобы скомпилировать все файлы классов в папке за один раз.

             jad -o -r -sjava -dsrc tree/**/*.class 
person Vinoth Kumar C M    schedule 06.06.2011

Используйте jd-gui, очень хороший декомпилятор, но компиляция... это будет болезненно.

person Op De Cirkel    schedule 06.06.2011

Прямо сейчас я делаю именно это, используя http://java.decompiler.free.fr/ для декомпиляции и помимо сравнения (http://www.scootersoftware.com/) для сравнения пакетов и файлов. Похоже, это отличная идея сделать быстрое сравнение с фактической версией (svn), скомпилированной и декомпилированной, чтобы проверить, какие файлы (и какие разделы) обновлены.

person Joan Sol    schedule 07.03.2012