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.

Antworten:


95

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 .


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

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

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.


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

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.


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.


0

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


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

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.