Confronto di due file .jar


93

Come si confrontano due file .jar? Entrambi hanno compilato file .class.

Voglio la differenza in termini di modifiche al metodo, ecc.

Risposte:


96

Andrey, qual è la differenza tra questi strumenti? Derivano dallo stesso nucleo?
Nikolay Kuznetsov

3
@NikolayKuznetsov, no, questi strumenti hanno un nucleo diverso. pkgdiff - confronto visivo delle dichiarazioni di classi, japi-compliance-checker e clirr - analisi dei cambiamenti (il primo è scritto in perl, il secondo - in java).
linuxbuild

Hai provato a integrare qualcosa con TeamCity? Sembra che clirr abbia un plugin Maven e che ci sia anche uno strumento chiamato JAPI-Checker.
Nikolay Kuznetsov

3
Nota che sia Japi-Compliance-Checker che Pkgdiff non confrontano tutto. Ad esempio, tutte le implementazioni del metodo vengono ignorate. Solo le firme dei metodi, le rimozioni dei metodi e le compatibilità API vengono generate come report. Se sei in grado di confrontare i binari, puoi scegliere di utilizzare strumenti come diff o cmp o plugin IntelliJ o anche Beyond Compare!
Sriram

22

Se selezioni due file in IntellijIdea e premi Ctrl + D, ti mostrerà il diff. Uso Ultimate e non so se funzionerà con l' edizione Community .


1
@ChristianNilsson, funziona nel 2018.2 su Mac 10.14 Mojave però
xuesheng,

Ho commesso l'errore di selezionare il wrapper Maven. Sotto Librerie esterne è necessario espandere il wrapper e quindi selezionare il file jar. Grazie @xuesheng
Christian Nilsson,

Soluzione super facile.
xandermonkey

Incredibile, questo è quello che stavo cercando :)
z1lV3r

18
  1. Rinomina .jar in .zip
  2. Estratto
  3. Decompilare i file di classe con jad
  4. Diff ricorsiva

2
È forza bruta, ma è esattamente il modo in cui lo farei. (Tranne che potrei usare jarper estrarre il contenuto, invece di rinominare il file e usarlo pkunzip.)
David R Tribble

2
Facoltativamente sostituire il passaggio 3 con una chiamata a javap -cper mantenerlo in bytecode (specialmente se con "modifiche al metodo" l'OP significava modifiche alla firma di un metodo).
Mark Peters

Come gestireste i corpi dei metodi spostati in alto o in basso nel file sorgente? Penso che sarebbe gettare diffl'ing del javapo jaduscita fuori Whack.
Marcus Junius Brutus


5

Estrai ogni jar nella sua directory usando il comando jar con i parametri xvf. cioè jar xvf myjar.jarper ogni barattolo.

Quindi, utilizzare il comando UNIX diffper confrontare le due directory. Questo mostrerà le differenze nelle directory. Puoi usare diff -r dir1 dir2due ricorsioni e mostrare le differenze nei file di testo in ogni directory (.xml, .properties, ecc.).

Questo mostrerà anche se i file di classe binaria differiscono. Per confrontare effettivamente i file di classe dovrai decompilarli come notato da altri.


3

Ecco il mio script per eseguire il processo descritto da 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}

Posso eseguirlo su Windows usando GIT per Windows. Basta aprire un prompt dei comandi. Esegui bash e quindi esegui lo script da lì.


2
Sembra che tu abbia perso l'ultima riga: diff -r ${EXT_DIR1} ${EXT_DIR2}o ${DIFF} ${EXT_DIR1} ${EXT_DIR2}(se riutilizzi la tua variabile dichiarata). Per coloro che sono su cygwin, lo script ha quasi funzionato per me tranne due cose che ho cambiato: 1) Ho dovuto usare javap integrato invece di jad, perché non posso scaricare jad (enterp. Firewall ... ); 2) come jar xfdoes't capire come i percorsi /cygwin/c/rest/of/pathche viene restituito da pwdin Cygwin, ho dovuto convertirlo in c:/rest/of/path: JAR_DIR=${PWD}, JAR_DIR=${JAR_DIR#*/cygdrive/c},JAR_DIR="c:$JAR_DIR"
PetroCliff

Hai ragione @dpg. L'ultima riga era $ {DIFF} $ {EXT_DIR1} $ {EXT_DIR2}
skanga

Che cos'è jad? Non ho quel binario disponibile in PATH
Filip

Jad è un decompilatore Java. Penso che non sia più mantenuto ma l'ho trovato disponibile su javadecompilers.com/jad
skanga

Nel caso in cui i tuoi argomenti (file jar) siano in una sottodirectory (come foo/bar/toto.jar), devi aggiungere l' -pargomento al comando mkdir
Duduche

2

In Linux / CygWin un pratico script che uso a volte è:

#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

Utilizzare Java Decompiler per trasformare il file jar in file di codice sorgente, quindi utilizzare WinMerge per eseguire il confronto.

Dovresti consultare il detentore del copyright del codice sorgente, per vedere se è corretto farlo.


1

usa il decompilatore java e decompila tutti i file .class e salva tutti i file come struttura del progetto.

quindi usa il visualizzatore di differenze di fusione e confronta come cartelle ..


0

Ecco uno strumento apparentemente gratuito http://www.extradata.com/products/jarc/


Grazie. Ho provato questo. Produce output in XML ed è necessaria un'ulteriore elaborazione per renderlo leggibile, se hai molte classi in .jar
Kunal

1
Per me si lamentava di un tools.jar mancante. Uso il JDK, quindi non è questo il problema. Penso che non supporti java7.
Roel Spilker

@ Tom il collegamento è interrotto, questa risposta potrebbe essere rimossa.
David Dossot

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.