ฉันจะเปรียบเทียบไฟล์. 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 dir2
recurse สองรายการและแสดงความแตกต่างของไฟล์ข้อความในแต่ละไดเร็กทอรี (.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/ - เครื่องมือเก่าและรายการอ้างอิงมีขนาดใหญ่ จากเอกสารดูเหมือนว่าน่าลอง