ฉันจะเปรียบเทียบไฟล์. jar สองไฟล์ได้อย่างไร ทั้งสองได้รวบรวมไฟล์. class
ฉันต้องการความแตกต่างในแง่ของการเปลี่ยนแปลงวิธีการ ฯลฯ
ฉันจะเปรียบเทียบไฟล์. jar สองไฟล์ได้อย่างไร ทั้งสองได้รวบรวมไฟล์. class
ฉันต้องการความแตกต่างในแง่ของการเปลี่ยนแปลงวิธีการ ฯลฯ
คำตอบ:
JAPICCตัวอย่างการใช้งาน:
japi-compliance-checker OLD.jar NEW.jar
ตัวอย่างรายงานสำหรับ log4j: http://abi-laboratory.pro/java/tracker/timeline/log4j/
PkgDiffตัวอย่างการใช้งาน:
pkgdiff OLD.jar NEW.jar
ดูรายงานตัวอย่างสำหรับ args4j
Clirrตัวอย่างการใช้งาน:
java -jar clirr-core-0.6-uber.jar -o OLD.jar -n NEW.jar
หากคุณเลือกสองไฟล์ในIntellijIdeaCtrl + Dแล้วกดมันจะแสดงความแตกต่าง ฉันใช้Ultimateและไม่รู้ว่ามันจะใช้ได้กับCommunity edition หรือไม่
jarเพื่อแยกเนื้อหาแทนที่จะเปลี่ยนชื่อไฟล์และใช้pkunzip)
javap -cให้เก็บไว้เป็น bytecode (โดยเฉพาะอย่างยิ่งถ้าโดย "วิธีการเปลี่ยนแปลง" OP หมายถึงการเปลี่ยนแปลงลายเซ็นของวิธีการ)
diffไอเท็มjavapหรือjadเอาท์พุทออกจากการตี
ฉันใช้กับZipDiff lib (มีทั้ง Java และ ant API)
แตกแต่ละ jar ไปยังไดเร็กทอรีของตัวเองโดยใช้คำสั่ง jar พร้อมพารามิเตอร์ xvf เช่นjar xvf myjar.jarสำหรับแต่ละโถ
จากนั้นใช้คำสั่ง UNIX diffเพื่อเปรียบเทียบทั้งสองไดเร็กทอรี สิ่งนี้จะแสดงความแตกต่างในไดเรกทอรี คุณสามารถใช้diff -r dir1 dir2recurse สองรายการและแสดงความแตกต่างของไฟล์ข้อความในแต่ละไดเร็กทอรี (.xml, .properties ฯลฯ )
สิ่งนี้จะแสดงด้วยว่าไฟล์คลาสไบนารีแตกต่างกันหรือไม่ ในการเปรียบเทียบไฟล์คลาสจริงๆคุณจะต้องถอดรหัสไฟล์ตามที่ผู้อื่นระบุไว้
นี่คือสคริปต์ของฉันในการทำกระบวนการที่อธิบายโดย 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}
ฉันสามารถรันบน Windows โดยใช้ GIT สำหรับ Windows เพียงแค่เปิดพรอมต์คำสั่ง เรียกใช้ bash จากนั้นเรียกใช้สคริปต์จากที่นั่น
diff -r ${EXT_DIR1} ${EXT_DIR2}หรือ${DIFF} ${EXT_DIR1} ${EXT_DIR2}(หากใช้ตัวแปรที่คุณประกาศซ้ำ) สำหรับผู้ที่ใช้ cygwin สคริปต์เกือบจะใช้ได้สำหรับฉันยกเว้นสองสิ่งที่ฉันเปลี่ยนไป: 1) ฉันต้องใช้ javap ในตัวแทน jad เพราะฉันไม่สามารถดาวน์โหลด jad (enterp. firewall ... ); 2) เป็นjar xfกวนเข้าใจเส้นทางเช่น/cygwin/c/rest/of/pathที่ถูกส่งกลับโดยpwdใน Cygwin ผมต้องแปลงเป็นc:/rest/of/path: JAR_DIR=${PWD}, JAR_DIR=${JAR_DIR#*/cygdrive/c},JAR_DIR="c:$JAR_DIR"
jad? ไม่มีไบนารีดังกล่าวใน PATH
foo/bar/toto.jar) คุณต้องเพิ่ม-pอาร์กิวเมนต์ในคำสั่ง mkdir
ใช้Java Decompilerเพื่อเปลี่ยนไฟล์ jar ให้เป็นไฟล์ซอร์สโค้ดจากนั้นใช้WinMergeเพื่อทำการเปรียบเทียบ
คุณควรปรึกษาผู้ถือลิขสิทธิ์ของซอร์สโค้ดเพื่อดูว่าสามารถทำได้หรือไม่
ใน Linux / CygWin สคริปต์ที่มีประโยชน์ที่ฉันใช้บางครั้งคือ:
#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
ใช้ตัว ถอดรหัส javaและถอดรหัสไฟล์. class ทั้งหมดและบันทึกไฟล์ทั้งหมดเป็นโครงสร้างโครงการ
จากนั้นใช้ meld diff viewer และเปรียบเทียบเป็นโฟลเดอร์ ..
นี่คือเครื่องมือฟรีที่ชัดเจนhttp://www.extradata.com/products/jarc/
โปรดลองhttp://www.osjava.org/jardiff/ - เครื่องมือเก่าและรายการอ้างอิงมีขนาดใหญ่ จากเอกสารดูเหมือนว่าน่าลอง