Порівняння двох файлів .jar


93

Як порівняти два файли .jar? Вони обидва склали файли .class.

Я хочу, щоб різниця в зміні методів тощо.

Відповіді:


95

Андрій, в чому різниця між цими інструментами? Вони походять від одного ядра?
Микола Кузнєцов

3
@NikolayKuznetsov, ні, ці інструменти мають різний стрижень. pkgdiff - візуальне порівняння декларацій класів, japi-відповідності-перевірки та clirr - аналіз змін (перша пишеться в perl, друга - у java).
linuxbuild

Ви намагалися щось інтегрувати з TeamCity? Здається, у clirr є плагін Maven, а також є інструмент під назвою JAPI-Checker.
Микола Кузнецов

3
Зверніть увагу, що Japi-Compliance-Checker і Pkgdiff не порівнюють все. Наприклад, усі реалізації методів ігноруються. У звіті створюються лише підписи методів, видалення методів та сумісність API. Якщо ви порівнюєте двійкові файли, тоді ви можете вибрати такі інструменти, як diff або cmp або плагін IntelliJ або навіть Більше порівняння!
Шрірам

22

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


1
@ChristianNilsson, працює в 2018.2 на Mac 10.14 Mojave
Čeprav

Я помилився, вибравши обгортку Maven. У розділі " Зовнішні бібліотеки" потрібно розгорнути обгортку, а потім вибрати jar-файл. Дякую @xuesheng
Крістіан Нільссон

Супер просте рішення.
xandermonkey

Дивно, ось що я шукав :)
z1lV3r

18
  1. Перейменуйте .jar у .zip
  2. Витяг
  3. Декомпілюйте файли класу з jad
  4. Рекурсивний розл

2
Це груба сила, але саме так я б це зробив. (За винятком того, що я можу використовувати jarдля вилучення вмісту, замість того, щоб перейменувати файл і використовувати pkunzip.)
David R Tribble

2
Необов’язково замініть крок 3 закликом javap -cтримати його в байт-коді (особливо якщо "зміна методу" ОП означала зміни в підписі методу).
Марк Петерс

Як би ви попрацювали з органами методів, які переміщуються вгору або вниз по вихідному файлу? Я думаю , що б кинути diffIng в javapабо jadвихід з їжачок.
Маркус Юній Брут


5

Витягніть кожен jar у свій власний каталог за допомогою команди 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}
сканга

Що таке 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 для порівняння.

Потрібно проконсультуватися з власником авторських прав на вихідний код, щоб побачити, чи правильно це робити.


1

використовувати Java-декомпілятор та декомпілювати всі файли .class та зберегти всі файли як структуру проекту.

потім скористайтеся засобом перегляду різниць та порівняйте як папки ..


0

Ось очевидно безкоштовний інструмент http://www.extradata.com/products/jarc/


Дякую. Я спробував цей. Він виробляє вихід у XML, і для подальшої обробки потрібна його читабельність, якщо у вас є багато класів у .jar
Kunal

1
Мені він скаржився на відсутні інструменти.jar. Я використовую JDK, так що це не проблема. Я думаю, що він не підтримує java7.
Roel Spilker

@ Якщо посилання розірвано, цю відповідь можна буде видалити.
Девід Доссо

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.