Comparando dos archivos .jar


93

¿Cómo comparo dos archivos .jar? Ambos han compilado archivos .class.

Quiero la diferencia en términos de cambios de método, etc.

Respuestas:


95

Andrey, ¿cuál es la diferencia entre esas herramientas? ¿Provienen del mismo núcleo?
Nikolay Kuznetsov

3
@NikolayKuznetsov, no, estas herramientas tienen un núcleo diferente. pkgdiff - comparación visual de declaraciones de clases, japi-compliance-checker y clirr - análisis de cambios (el primero está escrito en perl, el segundo - en java).
linuxbuild

¿Ha intentado integrar algo con TeamCity? Parece que clirr tiene un complemento de Maven y también hay una herramienta llamada JAPI-Checker.
Nikolay Kuznetsov

3
Tenga en cuenta que tanto Japi-Compliance-Checker como Pkgdiff no comparan todo. Por ejemplo, se ignoran todas las implementaciones de métodos. Solo se generan como informe las firmas de métodos, las eliminaciones de métodos y las compatibilidades de API. Si desea comparar binarios, puede optar por utilizar herramientas como diff o cmp o el complemento IntelliJ o incluso Beyond Compare.
Sriram

22

Si selecciona dos archivos en IntellijIdea y presiona Ctrl + D, se le mostrará la diferencia. Utilizo Ultimate y no sé si funcionará con la edición Community .


1
@ChristianNilsson, funciona en 2018.2 en Mac 10.14 Mojave aunque
xuesheng

Cometí el error de seleccionar la envoltura de Maven. En Bibliotecas externas, es necesario expandir el contenedor y luego seleccionar el archivo jar. Gracias @xuesheng
Christian Nilsson

Solución super fácil.
xandermonkey

Increíble, eso es lo que estaba buscando :)
z1lV3r

18
  1. Cambiar el nombre de .jar a .zip
  2. Extraer
  3. Descompilar archivos de clases con jad
  4. recursiva diff

2
Es fuerza bruta, pero así es exactamente como lo haría. (Excepto que podría usar jarpara extraer el contenido, en lugar de cambiar el nombre del archivo y usarlo pkunzip).
David R Tribble

2
Opcionalmente, reemplace el paso 3 con una llamada a javap -cpara mantenerlo en código de bytes (especialmente si por "cambios de método" el OP significa cambios en la firma de un método).
Mark Peters

¿Cómo lidiaría con los cuerpos de métodos que se mueven hacia arriba o hacia abajo en el archivo de origen? Creo que eso desequilibraría el diffing javapo la jadsalida.
Marcus Junius Brutus


5

Extraiga cada jar a su propio directorio usando el comando jar con los parámetros xvf. es decir, jar xvf myjar.jarpara cada frasco.

Luego, use el comando UNIX diffpara comparar los dos directorios. Esto mostrará las diferencias en los directorios. Puede usar diff -r dir1 dir2dos recurse y mostrar las diferencias en los archivos de texto en cada directorio (.xml, .properties, etc.).

Esto también mostrará si los archivos de clases binarios difieren. Para comparar realmente los archivos de clase, tendrá que descompilarlos como lo indicaron otros.


3

Aquí está mi script para hacer el proceso descrito por 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}

Puedo ejecutarlo en Windows usando GIT para Windows. Simplemente abra un símbolo del sistema. Ejecute bash y luego ejecute el script desde allí.


2
Parece que se perdió la última línea: diff -r ${EXT_DIR1} ${EXT_DIR2}o ${DIFF} ${EXT_DIR1} ${EXT_DIR2}(si reutiliza su variable declarada). Para aquellos que están en cygwin, el script casi funcionó para mí, excepto dos cosas que cambié: 1) Tuve que usar javap integrado en lugar de jad, porque no puedo descargar jad (enterp. Firewall ... ); 2) como jar xfdoes't entender caminos como la /cygwin/c/rest/of/pathque se devuelve pwden cygwin, tuve que convertirlo a c:/rest/of/path: JAR_DIR=${PWD}, JAR_DIR=${JAR_DIR#*/cygdrive/c},JAR_DIR="c:$JAR_DIR"
PetroCliff

Estás en lo correcto @dpg. La última línea era $ {DIFF} $ {EXT_DIR1} $ {EXT_DIR2}
skanga

¿Qué es jad? No tengo ese binario disponible en PATH
Filip

Jad es un descompilador de Java. Creo que ya no se mantiene, pero lo encontré disponible en javadecompilers.com/jad
skanga

En caso de que sus argumentos (archivos jar) estén en un subdirectorio (como foo/bar/toto.jar), debe agregar el -pargumento al comando mkdir
Duduche

2

En Linux / CygWin, un script útil que utilizo a veces es:

#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

Use Java Decompiler para convertir el archivo jar en un archivo de código fuente y luego use WinMerge para realizar la comparación.

Debe consultar al propietario de los derechos de autor del código fuente para ver si está bien hacerlo.


1

utilice el decompilador de Java y descompile todos los archivos .class y guarde todos los archivos como estructura de proyecto.

luego use el visor de diferencias de meld y compare como carpetas.


0

Aquí hay una herramienta aparentemente gratuita http://www.extradata.com/products/jarc/


Gracias. Probé este. Produce resultados en XML y se requiere un procesamiento adicional para que sea legible, si tiene muchas clases en .jar
Kunal

1
Para mí, se quejó de que faltaba un tools.jar. Yo uso el JDK, así que ese no es el problema. Creo que no es compatible con java7.
Roel Spilker

@Tom el enlace está roto, esta respuesta podría eliminarse.
David Dossot

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.