Porównanie dwóch plików .jar

94

Jak porównać dwa pliki .jar? Obaj skompilowali pliki .class.

Chcę różnicy w zakresie zmian metod itp.

Kunal
źródło

Odpowiedzi:

96
linuxbuild
źródło
Andrey, jaka jest różnica między tymi narzędziami? Czy pochodzą z tego samego rdzenia?
Nikolay Kuznetsov,
3
@NikolayKuznetsov, nie, te narzędzia mają inny rdzeń. pkgdiff - wizualne porównanie deklaracji klas, japi-compliance-checker i clirr - analiza zmian (pierwsza napisana w perlu, druga - w java).
linuxbuild
Czy próbowałeś zintegrować coś z TeamCity? Wygląda na to, że clirr ma wtyczkę Maven i jest też narzędzie o nazwie JAPI-Checker.
Nikolay Kuznetsov,
3
Należy pamiętać, że zarówno Japi-Compliance-Checker, jak i Pkgdiff nie porównują wszystkiego. Na przykład wszystkie implementacje metod są ignorowane. W raporcie są generowane tylko podpisy metod, usunięcia metod i zgodności interfejsu API. Jeśli jesteś w stanie porównać pliki binarne, możesz zdecydować się na użycie narzędzi takich jak diff lub cmp, wtyczka IntelliJ lub nawet Beyond Compare!
Sriram
25

Jeśli wybierzesz dwa pliki w IntellijIdea i naciśniesz, Ctrl + Dto pokaże ci różnicę. Używam wersji Ultimate i nie wiem, czy będzie działać w wersji Community .

xuesheng
źródło
1
@ChristianNilsson, działa w 2018.2 na Macu 10.14 Mojave chociaż
xuesheng
Popełniłem błąd, wybierając opakowanie Maven. W Bibliotekach zewnętrznych należy rozwinąć opakowanie, a następnie wybrać plik jar. Dzięki @xuesheng
Christian Nilsson
Super łatwe rozwiązanie.
xandermonkey
Niesamowite, tego szukałem :)
z1lV3r
18
  1. Zmień nazwę .jar na .zip
  2. Wyciąg
  3. Dekompiluj pliki klas za pomocą jad
  4. rekurencyjna diff
sje397
źródło
2
To brutalna siła, ale dokładnie tak bym to zrobił. (Z wyjątkiem tego, że mógłbym użyć jardo wyodrębnienia zawartości, zamiast zmiany nazwy pliku i używania pkunzip.)
David R Tribble,
2
Opcjonalnie zamień krok 3 na wywołanie, aby javap -czachować kod bajtowy (zwłaszcza jeśli przez „zmiany metody” OP oznaczało zmiany w sygnaturze metody).
Mark Peters
Jak poradzisz sobie z przenoszeniem treści metod w górę lub w dół pliku źródłowego? Myślę, że to by diffzniweczyło javaplub jadwyjście z walki.
Marcus Junius Brutus
5

Używam do ZipDiff lib (mam zarówno Java, jak i ANT API).

FoxyBOA
źródło
5

Rozpakuj każdy plik jar do jego własnego katalogu za pomocą polecenia jar z parametrami xvf. to znaczyjar xvf myjar.jar dla każdego słoika.

Następnie użyj polecenia UNIX, diffaby porównać dwa katalogi. To pokaże różnice w katalogach. Możesz użyć diff -r dir1 dir2dwóch powtórzeń i pokazać różnice w plikach tekstowych w każdym katalogu (.xml, .properties itp.).

To również pokaże, czy pliki klas binarnych się różnią. Aby faktycznie porównać pliki klas, będziesz musiał je zdekompilować, jak zauważyli inni.

Brian
źródło
3

Oto mój skrypt do wykonania procesu opisanego przez 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}

Mogę go uruchomić w systemie Windows za pomocą GIT dla Windows. Po prostu otwórz wiersz polecenia. Uruchom bash, a następnie wykonaj skrypt stamtąd.

skanga
źródło
2
Wygląda na to, że przegapiłeś ostatnią linię: diff -r ${EXT_DIR1} ${EXT_DIR2}lub ${DIFF} ${EXT_DIR1} ${EXT_DIR2}(jeśli ponownie użyj zadeklarowanej zmiennej). Dla tych, którzy są na cygwin, skrypt prawie działał dla mnie, z wyjątkiem dwóch rzeczy, które zmieniłem: 1) Musiałem użyć wbudowanego javapa zamiast jad, ponieważ nie mogę pobrać jad (enterp. Firewall ... ); 2) jako jar xfdoes't zrozumieć jak ścieżki /cygwin/c/rest/of/path, który jest zwracany przez pwdw Cygwin, miałem go przekonwertować do c:/rest/of/path: JAR_DIR=${PWD}, JAR_DIR=${JAR_DIR#*/cygdrive/c},JAR_DIR="c:$JAR_DIR"
PetroCliff
Masz rację @dpg. Ostatnia linia to $ {DIFF} $ {EXT_DIR1} $ {EXT_DIR2}
skanga
Co to jest jad? Nie miej tego pliku binarnego dostępnego w PATH
Filip
Jad to dekompilator Java. Myślę, że nie jest już utrzymywane, ale znalazłem je dostępne na javadecompilers.com/jad
skanga
Jeśli twoje argumenty (pliki jar) znajdują się w podkatalogu (takim jak foo/bar/toto.jar), musisz dodać -pargument do polecenia mkdir
Duduche,
2

W systemie Linux / CygWin przydatnym skryptem, którego czasami używam, jest:

#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
źródło
1

Użyj programu Java Decompiler, aby przekształcić plik jar w plik kodu źródłowego, a następnie użyj programu WinMerge, aby przeprowadzić porównanie.

Powinieneś skonsultować się z właścicielem praw autorskich do kodu źródłowego, aby sprawdzić, czy jest to w porządku.

Cheok Yan Cheng
źródło
1

użyj dekompilatora java i zdekompiluj wszystkie pliki .class i zapisz wszystkie pliki jako strukturę projektu.

następnie użyj przeglądarki meld diff i porównaj jako foldery.

Dulip Chandana
źródło
0

Oto pozornie darmowe narzędzie http://www.extradata.com/products/jarc/

Tomek
źródło
Dzięki. Próbowałem tego. Tworzy dane wyjściowe w formacie XML i wymagane jest dalsze przetwarzanie, aby uczynić je czytelnymi, jeśli masz wiele klas w .jar
Kunal
1
Mnie narzekał na brakujący plik tools.jar. Używam JDK, więc to nie jest problem. Myślę, że nie obsługuje java7.
Roel Spilker,
@Tom link jest uszkodzony, tę odpowiedź można usunąć.
David Dossot,