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


94

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

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

Ответы:


96

Андрей, в чем разница между этими инструментами? Происходят ли они из одного ядра?
Николай Кузнецов

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 .


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

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

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/ - инструмент старый, а список зависимостей большой. Судя по документации, похоже, стоит попробовать.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.