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.

Réponses:


96

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 .


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

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

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.


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à.


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

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.


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.


0

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


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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.