Vergleichen von zwei JAR-Dateien

93

Wie vergleiche ich zwei JAR-Dateien? Beide haben .class-Dateien kompiliert.

Ich möchte den Unterschied in Bezug auf Methodenänderungen usw.

Kunal
quelle

Antworten:

95
Linuxbuild
quelle
Andrey, was ist der Unterschied zwischen diesen Werkzeugen? Entstehen sie demselben Kern?
Nikolay Kuznetsov
3
@ NikolayKuznetsov, nein, diese Tools haben einen anderen Kern. pkgdiff - visueller Vergleich von Klassendeklarationen, Japi-Compliance-Checker und Clirr - Analyse von Änderungen (die erste ist in Perl geschrieben, die zweite in Java).
Linuxbuild
Haben Sie versucht, etwas in TeamCity zu integrieren? Es scheint, dass Clirr ein Maven-Plugin hat und es auch ein Tool namens JAPI-Checker gibt.
Nikolay Kuznetsov
3
Bitte beachten Sie, dass sowohl Japi-Compliance-Checker als auch Pkgdiff nicht alles vergleichen. Beispielsweise werden alle Methodenimplementierungen ignoriert. Als Bericht werden nur Methodensignaturen, Methodenentfernungen und API-Kompatibilitäten generiert. Wenn Sie Binärdateien vergleichen möchten, können Sie Tools wie diff oder cmp oder IntelliJ Plugin oder sogar Beyond Compare verwenden!
Sriram
22

Wenn Sie in IntellijIdea zwei Dateien auswählen und drücken Ctrl + D, wird der Unterschied angezeigt . Ich benutze Ultimate und weiß nicht, ob es mit der Community Edition funktioniert .

xuesheng
quelle
1
@ChristianNilsson, arbeitet in 2018.2 auf Mac 10.14 Mojave obwohl
Xuesheng
Ich habe den Fehler gemacht, den Maven-Wrapper auszuwählen. Unter Externe Bibliotheken muss der Wrapper erweitert und dann die JAR-Datei ausgewählt werden. Danke @xuesheng
Christian Nilsson
Super einfache Lösung.
Xandermonkey
Erstaunlich, dass ich danach gesucht habe :)
z1lV3r
18
  1. Benennen Sie .jar in .zip um
  2. Extrakt
  3. Dekompilieren Sie Klassendateien mit jad
  4. Rekursives Diff
sje397
quelle
2
Es ist rohe Gewalt, aber genau so würde ich es machen. (Außer, dass ich verwenden könnte jar, um den Inhalt zu extrahieren, anstatt die Datei pkunzip
umzubenennen
2
Ersetzen Sie Schritt 3 optional durch einen Aufruf, javap -cum den Bytecode beizubehalten (insbesondere, wenn durch "Methodenänderungen" das OP Änderungen an der Signatur einer Methode bedeutete).
Mark Peters
Wie würden Sie mit Methodenkörpern umgehen, die in der Quelldatei nach oben oder unten verschoben werden? Ich denke , dass die werfen würde diffing von javapoder jadAusgang aus dem Gleichgewicht geraten.
Marcus Junius Brutus
5

Ich benutze ZipDiff lib (habe sowohl Java als auch Ant API).

FoxyBOA
quelle
5

Extrahieren Sie jedes Glas mit dem Befehl jar mit den Parametern xvf in ein eigenes Verzeichnis. dh jar xvf myjar.jarfür jedes Glas.

Verwenden Sie dann den UNIX-Befehl diff, um die beiden Verzeichnisse zu vergleichen. Dies zeigt die Unterschiede in den Verzeichnissen. Sie können diff -r dir1 dir2zwei Rekursionen verwenden und die Unterschiede in den Textdateien in jedem Verzeichnis (.xml, .properties usw.) anzeigen.

Dies zeigt auch, ob sich Binärklassendateien unterscheiden. Um die Klassendateien tatsächlich zu vergleichen, müssen Sie sie wie von anderen angegeben dekompilieren.

Brian
quelle
2

In Linux / CygWin ist ein praktisches Skript, das ich manchmal verwende:

#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
quelle
2

Hier ist mein Skript, um den von sje397 beschriebenen Prozess auszuführen:

    #!/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}

Ich kann es unter Windows mit GIT für Windows ausführen. Öffnen Sie einfach eine Eingabeaufforderung. Führen Sie bash aus und führen Sie das Skript von dort aus aus.

Skanga
quelle
2
Scheint, als hätten Sie die letzte Zeile verpasst: diff -r ${EXT_DIR1} ${EXT_DIR2}oder ${DIFF} ${EXT_DIR1} ${EXT_DIR2}(wenn Sie Ihre deklarierte Variable wiederverwenden). Für diejenigen, die auf Cygwin sind, hat das Skript fast für mich funktioniert, außer zwei Dingen, die ich geändert habe: 1) Ich musste eingebautes Javap anstelle von Jad verwenden, da ich Jad nicht herunterladen kann (enterp. Firewall ... ); 2) als jar xfdoes't Pfade verstehen wie /cygwin/c/rest/of/pathdem zurück von pwdin Cygwin, musste ich es konvertieren c:/rest/of/path: JAR_DIR=${PWD}, JAR_DIR=${JAR_DIR#*/cygdrive/c},JAR_DIR="c:$JAR_DIR"
PetroCliff
Sie sind richtig @dpg. Die letzte Zeile war $ {DIFF} $ {EXT_DIR1} $ {EXT_DIR2}
Skanga
Was ist jad? Haben Sie diese Binärdatei nicht in PATH
Filip
Jad ist ein Java Decompiler. Ich denke, es wird nicht mehr gewartet, aber ich fand es verfügbar unter javadecompilers.com/jad
skanga
Falls sich Ihre Argumente (JAR-Dateien) in einem Unterverzeichnis (wie foo/bar/toto.jar) befinden, müssen Sie das -pArgument zum Befehl mkdir hinzufügen
Duduche
1

Verwenden Sie Java Decompiler , um die JAR-Datei in eine Quellcodedatei umzuwandeln, und verwenden Sie dann WinMerge , um einen Vergleich durchzuführen.

Sie sollten den Inhaber des Urheberrechts des Quellcodes konsultieren, um festzustellen, ob dies in Ordnung ist.

Cheok Yan Cheng
quelle
0

Hier ist ein anscheinend kostenloses Tool: http://www.extradata.com/products/jarc/

Tom
quelle
Vielen Dank. Ich habe es versucht. Es erzeugt eine Ausgabe in XML und eine weitere Verarbeitung ist erforderlich, um es lesbar zu machen, wenn Sie viele Klassen in .jar
Kunal
1
Bei mir hat es sich über ein fehlendes tools.jar beschwert. Ich benutze das JDK, das ist also nicht das Problem. Ich denke, es unterstützt Java7 nicht.
Roel Spilker
@Der Link ist defekt, diese Antwort könnte entfernt werden.
David Dossot
0

Bitte versuchen Sie es mit http://www.osjava.org/jardiff/ - das Tool ist alt und die Abhängigkeitsliste ist groß. Aus den Dokumenten geht hervor, dass es sich lohnt, es zu versuchen.

Jayan
quelle
0

Verwenden Sie den Java-Dekompiler und dekompilieren Sie alle .class-Dateien und speichern Sie alle Dateien als Projektstruktur.

Verwenden Sie dann den Meld Diff Viewer und vergleichen Sie ihn als Ordner.

Dulip Chandana
quelle