Сравнение двух файлов .jar

94

Как сравнить два файла .jar? Оба они скомпилировали файлы .class.

Я хочу разницу в изменении методов и т. Д.

Кунал
источник

Ответы:

96
linuxbuild
источник
Андрей, в чем разница между этими инструментами? Происходят ли они из одного ядра?
Николай Кузнецов
3
@NikolayKuznetsov, нет, у этих инструментов другое ядро. pkgdiff - визуальное сравнение объявлений классов, japi-compliance-checker и clirr - анализ изменений (первое написано на perl, второе - на java).
linuxbuild
Вы пробовали что-то интегрировать с TeamCity? Кажется, у clirr есть плагин Maven, а также инструмент под названием JAPI-Checker.
Николай Кузнецов
3
Обратите внимание, что и Japi-Compliance-Checker, и Pkgdiff не сравнивают все. Например, игнорируются все реализации методов. В виде отчета создаются только сигнатуры методов, удаления методов и совместимость API. Если вы хотите сравнивать двоичные файлы, вы можете использовать такие инструменты, как diff, cmp, плагин IntelliJ или даже Beyond Compare!
Шрирам
25

Если вы выберете два файла в IntellijIdea и нажмете,Ctrl + D он покажет вам разницу. Я использую Ultimate и не знаю, будет ли он работать с версией Community .

Xuesheng
источник
1
@ChristianNilsson, работает в 2018.2 на Mac 10.14 Mojave, хотя
xuesheng
Я совершил ошибку, выбрав оболочку Maven. В разделе « Внешние библиотеки» нужно развернуть оболочку, а затем выбрать jar-файл. Спасибо @xuesheng
Christian Nilsson
Супер простое решение.
xandermonkey
Удивительно, вот что я искал :)
z1lV3r
18
  1. Переименуйте .jar в .zip
  2. Извлечь
  3. Декомпилируйте файлы классов с помощью jad
  4. Рекурсивный diff
sje397
источник
2
Это грубая сила, но я бы так и поступил. (За исключением того, что я мог бы использовать jarдля извлечения содержимого, вместо того, чтобы переименовывать файл и использовать pkunzip.)
Дэвид Р. Триббл
2
При желании замените шаг 3 на вызов, чтобы javap -cсохранить его в байт-коде (особенно, если под «изменением метода» OP подразумевает изменение подписи метода).
Марк Питерс
Как бы вы справились с перемещением тел методов вверх или вниз по исходному файлу? Я думаю , что бы бросить diffIng в javapили jadвыход из ежик.
Marcus Junius Brutus
5

Извлеките каждую банку в ее собственный каталог с помощью команды jar с параметрами xvf. т.е. jar xvf myjar.jarдля каждой баночки.

Затем используйте команду UNIX diffдля сравнения двух каталогов. Это покажет различия в каталогах. Вы можете использовать diff -r dir1 dir2две рекурсии и отображать различия в текстовых файлах в каждом каталоге (.xml, .properties и т. Д.).

Это также покажет, отличаются ли файлы двоичных классов. Чтобы на самом деле сравнить файлы классов, вам придется декомпилировать их, как отметили другие.

Брайан
источник
3

Вот мой сценарий для выполнения процесса, описанного sje397:

    #!/bin/sh

    # Needed if running on Windows
    FIND="/usr/bin/find"
    DIFF="diff -r"

    # Extract the jar (war or ear)
    JAR_FILE1=$1
    JAR_FILE2=$2

    JAR_DIR=${PWD}          # to assign to a variable
    TEMP_DIR=$(mktemp -d)

    echo "Extracting jars in $TEMP_DIR"

    EXT_DIR1="${TEMP_DIR}/${JAR_FILE1%.*}"
    EXT_DIR2="${TEMP_DIR}/${JAR_FILE2%.*}"

    mkdir ${EXT_DIR1}
    cd ${EXT_DIR1}
    jar xf ${JAR_DIR}/${JAR_FILE1}
    jad -d . -o -t2 -safe -space -b -ff -s java -r **/*.class
    cd ..

    mkdir ${EXT_DIR2}
    cd ${EXT_DIR2}
    jar xf ${JAR_DIR}/${JAR_FILE2}
    jad -d . -o -t2 -safe -space -b -ff -s java -r **/*.class
    cd ..

    # remove class files so the diff is clean
    ${FIND} ${TEMP_DIR} -name '*.class' | xargs rm

    # diff recursively 
    ${DIFF} ${EXT_DIR1} ${EXT_DIR2}

Я могу запустить его в Windows, используя GIT для Windows. Просто откройте командную строку. Запустите bash, а затем выполните сценарий оттуда.

сканга
источник
2
Похоже, вы пропустили последнюю строку: diff -r ${EXT_DIR1} ${EXT_DIR2}или ${DIFF} ${EXT_DIR1} ${EXT_DIR2}(если повторно используете объявленную переменную). Для тех, кто использует cygwin, сценарий почти работал у меня, за исключением двух вещей, которые я изменил: 1) Мне пришлось использовать встроенный javap вместо jad, потому что я не могу загрузить jad (enterp. Firewall ... ); 2) в качестве jar xfdoes't понять пути , как , /cygwin/c/rest/of/pathкоторый возвращается pwdв Cygwin, я должен был преобразовать его в c:/rest/of/path: JAR_DIR=${PWD}, JAR_DIR=${JAR_DIR#*/cygdrive/c},JAR_DIR="c:$JAR_DIR"
PetroCliff
Вы правы @dpg. Последняя строка была $ {DIFF} $ {EXT_DIR1} $ {EXT_DIR2}
skanga
Что есть jad?
Филип
Jad - это декомпилятор Java. Я думаю, что он больше не поддерживается, но я нашел его доступным на javadecompilers.com/jad
skanga
Если ваши аргументы (файлы jar) находятся в подкаталоге (например foo/bar/toto.jar), вам нужно добавить -pаргумент в команду mkdir
Duduche
2

В Linux / CygWin я иногда использую удобный сценарий:

#Extract the jar (war or ear)
cd dir1
jar xvf jar-file1
for i in `ls *.class`
do
 javap $i > ${i}.txt #list the functions/variables etc
done

cd dir2
jar xvf jar-file2
for i in `ls *.class`
do
 javap $i > ${i}.txt #list the functions/variables etc
done

diff -r dir1 dir2 #diff recursively
SidJ
источник
1

Используйте Java Decompiler, чтобы превратить файл jar в файл исходного кода, а затем используйте WinMerge для выполнения сравнения.

Вам следует проконсультироваться с правообладателем исходного кода, чтобы узнать, можно ли это сделать.

Чеок Ян Ченг
источник
0

Вот, по-видимому, бесплатный инструмент http://www.extradata.com/products/jarc/

Том
источник
Спасибо. Я пробовал это. Он производит вывод в формате XML, и требуется дальнейшая обработка, чтобы сделать его читабельным, если у вас много классов в .jar
Кунал
1
Мне он жаловался на отсутствие tools.jar. Я использую JDK, так что проблема не в этом. Я думаю, он не поддерживает java7.
Роэл Спилкер
@Tom ссылка не работает, этот ответ может быть удален.
Дэвид Доссот
0

Пожалуйста, попробуйте http://www.osjava.org/jardiff/ - инструмент старый, а список зависимостей большой. Судя по документации, похоже, стоит попробовать.

Джаян
источник