Membandingkan dua file .jar


93

Bagaimana cara membandingkan dua file .jar? Keduanya telah mengkompilasi file .class.

Saya ingin perbedaan dalam hal perubahan metode, dll.

Jawaban:


96

Andrey, apa bedanya alat-alat itu? Apakah mereka berasal dari inti yang sama?
Nikolay Kuznetsov

3
@NikolayKuznetsov, tidak, alat ini memiliki inti yang berbeda. pkgdiff - perbandingan visual deklarasi class, japi-compliance-checker dan clirr - analisis perubahan (yang pertama ditulis dalam perl, yang kedua - dalam java).
linuxbuild

Sudahkah Anda mencoba mengintegrasikan sesuatu dengan TeamCity? Tampaknya clirr memiliki Plugin Maven dan ada juga alat yang disebut JAPI-Checker.
Nikolay Kuznetsov

3
Harap dicatat bahwa Japi-Compliance-Checker dan Pkgdiff tidak membandingkan semuanya. Misalnya, semua implementasi metode diabaikan. Hanya tanda tangan metode, penghapusan metode, dan kompatibilitas API yang dibuat sebagai laporan. Jika Anda ingin membandingkan binari, maka Anda dapat memilih untuk menggunakan alat seperti diff atau cmp atau plugin IntelliJ atau bahkan Beyond Compare!
Sriram

23

Jika Anda memilih dua file di IntellijIdea dan menekannya, Ctrl + Dmaka Anda akan melihat perbedaannya. Saya menggunakan Ultimate dan tidak tahu apakah itu akan berfungsi dengan edisi Komunitas .


1
@ChristianNilsson, bekerja pada 2018.2 pada Mac 10.14 Mojave meskipun
xuesheng

Saya membuat kesalahan dengan memilih pembungkus Maven. Di bawah Perpustakaan Eksternal, seseorang perlu memperluas pembungkusnya dan kemudian memilih file jar. Terima kasih @xuesheng
Christian Nilsson

Solusi super mudah.
xandermonkey

Luar biasa itulah yang saya cari :)
z1lV3r

18
  1. Ubah nama .jar menjadi .zip
  2. Ekstrak
  3. Dekompilasi file kelas dengan jad
  4. rekursif diff

2
Ini kekerasan, tapi itulah cara saya melakukannya. (Kecuali yang mungkin saya gunakan jaruntuk mengekstrak konten, alih-alih mengganti nama file dan menggunakan pkunzip.)
David R Tribble

2
Secara opsional, ganti langkah 3 dengan panggilan untuk javap -cmenyimpannya ke bytecode (terutama jika dengan "perubahan metode", OP berarti perubahan pada tanda tangan metode).
Mark Peters

Bagaimana Anda menangani badan metode yang dipindahkan ke atas atau ke bawah file sumber? Saya berpikir bahwa akan membuang diffing dari javapatau jadkeluaran dari mendera.
Marcus Junius Brutus


5

Ekstrak setiap jar ke direktorinya sendiri menggunakan perintah jar dengan parameter xvf. yaitujar xvf myjar.jar untuk setiap toples.

Kemudian, gunakan perintah UNIX diffuntuk membandingkan dua direktori. Ini akan menunjukkan perbedaan direktori. Anda dapat menggunakan diff -r dir1 dir2dua pengulangan dan menunjukkan perbedaan file teks di setiap direktori (.xml, .properties, dll).

Ini juga akan menunjukkan jika file kelas biner berbeda. Untuk benar-benar membandingkan file kelas Anda harus mendekompilasi mereka seperti yang dicatat oleh orang lain.


3

Berikut ini skrip saya untuk melakukan proses yang dijelaskan oleh 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}

Saya dapat menjalankannya di Windows menggunakan GIT untuk Windows. Buka saja prompt perintah. Jalankan bash dan kemudian jalankan skrip dari sana.


2
Tampaknya Anda melewatkan baris terakhir: diff -r ${EXT_DIR1} ${EXT_DIR2}atau ${DIFF} ${EXT_DIR1} ${EXT_DIR2}(jika menggunakan kembali variabel yang Anda deklarasikan). Bagi mereka yang menggunakan cygwin, skripnya hampir berfungsi untuk saya kecuali dua hal yang telah saya ubah: 1) Saya harus menggunakan javap bawaan daripada jad, karena saya tidak dapat mengunduh jad (enterp. Firewall ... ); 2) sebagai jar xfdoes't memahami jalur seperti /cygwin/c/rest/of/pathyang dikembalikan oleh pwddi cygwin, saya harus mengubahnya menjadi c:/rest/of/path: JAR_DIR=${PWD}, JAR_DIR=${JAR_DIR#*/cygdrive/c},JAR_DIR="c:$JAR_DIR"
PetroCliff

Anda benar @dpg. Baris terakhir adalah $ {DIFF} $ {EXT_DIR1} $ {EXT_DIR2}
skanga

Apa jad? Tidak memiliki biner yang tersedia di PATH
Filip

Jad adalah Decompiler Java. Saya pikir itu tidak dipertahankan lagi tetapi saya menemukannya tersedia di javadecompilers.com/jad
skanga

Jika argumen Anda (file jar) berada dalam subdirektori (seperti foo/bar/toto.jar), Anda perlu menambahkan -pargumen ke perintah mkdir
Duduche

2

Di Linux / CygWin, skrip praktis yang terkadang saya gunakan adalah:

#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

Gunakan Java Decompiler untuk mengubah file jar menjadi file kode sumber, dan kemudian gunakan WinMerge untuk melakukan perbandingan.

Anda harus berkonsultasi dengan pemegang hak cipta dari kode sumber, untuk mengetahui apakah boleh dilakukan.


1

gunakan java decompiler dan dekompilasi semua file .class dan simpan semua file sebagai struktur proyek.

lalu gunakan meld diff viewer dan bandingkan sebagai folder ..


0

Ini alat yang benar-benar gratis http://www.extradata.com/products/jarc/


Terima kasih. Saya mencoba yang ini. Ini menghasilkan keluaran dalam XML dan pemrosesan lebih lanjut diperlukan agar dapat dibaca, jika Anda memiliki banyak kelas dalam .jar
Kunal

1
Bagi saya itu mengeluh tentang tools.jar yang hilang. Saya menggunakan JDK, jadi bukan itu masalahnya. Saya pikir itu tidak mendukung java7.
Roel Spilker

@Tom tautannya rusak, jawaban ini dapat dihapus.
David Dossot

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.