Comparaison de deux fichiers .jar

93

Comment comparer deux fichiers .jar? Tous deux ont compilé des fichiers .class.

Je veux la différence en termes de changements de méthode, etc.

Kunal
la source

Réponses:

96
linuxbuild
la source
Andrey, quelle est la différence entre ces outils? Viennent-ils du même noyau?
Nikolay Kuznetsov
3
@NikolayKuznetsov, non, ces outils ont un noyau différent. pkgdiff - comparaison visuelle des déclarations de classes, japi-compliance-checker et clirr - analyse des changements (le premier est écrit en perl, le second - en java).
linuxbuild
Avez-vous essayé d'intégrer quelque chose avec TeamCity? Il semble que clirr possède un plugin Maven et il existe également un outil appelé JAPI-Checker.
Nikolay Kuznetsov
3
Veuillez noter que Japi-Compliance-Checker et Pkgdiff ne comparent pas tout. Par exemple, toutes les implémentations de méthode sont ignorées. Seules les signatures de méthode, les suppressions de méthodes et les compatibilités API sont générées sous forme de rapport. Si vous êtes prêt à comparer des binaires, vous pouvez choisir d'utiliser des outils comme diff ou cmp ou le plugin IntelliJ ou même Beyond Compare!
Sriram
22

Si vous sélectionnez deux fichiers dans IntellijIdea et appuyez sur, Ctrl + Dil vous montrera le diff. J'utilise Ultimate et je ne sais pas si cela fonctionnera avec l' édition communautaire .

xuesheng
la source
1
@ChristianNilsson, fonctionne en 2018.2 sur Mac 10.14 Mojave cependant
xuesheng
J'ai fait l'erreur de sélectionner le wrapper Maven. Sous Bibliothèques externes, vous devez développer le wrapper, puis sélectionner le fichier jar. Merci @xuesheng
Christian Nilsson
Solution super facile.
xandermonkey
Incroyable c'est ce que je cherchais :)
z1lV3r
18
  1. Renommez .jar en .zip
  2. Extrait
  3. Décompiler les fichiers de classe avec jad
  4. récursive diff
sje397
la source
2
C'est la force brute, mais c'est exactement comme ça que je le ferais. (Sauf que je pourrais utiliser jarpour extraire le contenu, au lieu de renommer le fichier et de l'utiliser pkunzip.)
David R Tribble
2
Remplacez éventuellement l'étape 3 par un appel à javap -cpour le conserver au bytecode (surtout si par "method changes" l'OP signifiait des changements dans la signature d'une méthode).
Mark Peters
Comment gérez-vous le déplacement des corps de méthode vers le haut ou vers le bas du fichier source? Je pense que cela déséquilibrerait l' diffing javapou la jadsortie.
Marcus Junius Brutus
5

J'utilise pour ZipDiff lib (j'ai à la fois Java et ant API).

FoxyBOA
la source
5

Extrayez chaque fichier jar dans son propre répertoire à l'aide de la commande jar avec les paramètres xvf. c'est à direjar xvf myjar.jar à- pour chaque pot.

Ensuite, utilisez la commande UNIX diffpour comparer les deux répertoires. Cela montrera les différences dans les répertoires. Vous pouvez utiliserdiff -r dir1 dir2 deux recurse et afficher les différences dans les fichiers texte dans chaque répertoire (.xml, .properties, etc.).

Cela montrera également si les fichiers de classe binaire diffèrent. Pour comparer réellement les fichiers de classe, vous devrez les décompiler comme indiqué par d'autres.

Brian
la source
3

Voici mon script pour faire le processus décrit par 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}

Je peux l'exécuter sur Windows en utilisant GIT pour Windows. Ouvrez simplement une invite de commande. Exécutez bash, puis exécutez le script à partir de là.

skanga
la source
2
Il semble que vous ayez manqué la dernière ligne: diff -r ${EXT_DIR1} ${EXT_DIR2}ou ${DIFF} ${EXT_DIR1} ${EXT_DIR2}(si vous réutilisez votre variable déclarée). Pour ceux qui sont sur cygwin, le script a presque fonctionné pour moi, sauf deux choses que j'ai changées: 1) J'ai dû utiliser javap intégré au lieu de jad, car je ne peux pas télécharger jad (enterp. Firewall ... ); 2) jar xfdoes't comprendre des chemins comme /cygwin/c/rest/of/pathqui est retourné par pwddans Cygwin, je devais le convertir en c:/rest/of/path: JAR_DIR=${PWD}, JAR_DIR=${JAR_DIR#*/cygdrive/c},JAR_DIR="c:$JAR_DIR"
PetroCliff
Vous avez raison @dpg. La dernière ligne était $ {DIFF} $ {EXT_DIR1} $ {EXT_DIR2}
skanga
Qu'est-ce que c'est jad? Ne pas avoir ce binaire disponible dans PATH
Filip
Jad est un décompilateur Java. Je pense qu'il n'est plus maintenu mais je l'ai trouvé disponible sur javadecompilers.com/jad
skanga
foo/bar/toto.jarSi vos arguments (fichiers jar) sont dans un sous-répertoire (comme ), vous devez ajouter l' -pargument à la commande mkdir
Duduche
2

Dans Linux / CygWin, un script pratique que j'utilise parfois est:

#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
SidJ
la source
1

Utilisez Java Decompiler pour transformer le fichier jar en fichier de code source, puis utilisez WinMerge pour effectuer la comparaison.

Vous devriez consulter le détenteur des droits d'auteur du code source, pour voir s'il est acceptable de le faire.

Cheok Yan Cheng
la source
1

utiliser le décompilateur java et décompilez tous les fichiers .class et enregistrez tous les fichiers en tant que structure de projet.

puis utilisez meld diff viewer et comparez en tant que dossiers.

Dulip Chandana
la source
0

Voici un outil totalement gratuit http://www.extradata.com/products/jarc/

À M
la source
Merci. J'ai essayé celui-ci. Il produit une sortie en XML et un traitement supplémentaire est nécessaire pour le rendre lisible, si vous avez de nombreuses classes dans .jar
Kunal
1
Pour moi, il se plaignait d'un tools.jar manquant. J'utilise le JDK, donc ce n'est pas le problème. Je pense qu'il ne prend pas en charge java7.
Roel Spilker
@Tom le lien est rompu, cette réponse pourrait être supprimée.
David Dossot