Comparando dois arquivos .jar


93

Como posso comparar dois arquivos .jar? Ambos compilaram arquivos .class.

Eu quero a diferença em termos de mudanças de método, etc.

Respostas:


96

Andrey, qual é a diferença entre essas ferramentas? Eles vêm do mesmo núcleo?
Nikolay Kuznetsov

3
@NikolayKuznetsov, não, essas ferramentas têm núcleos diferentes. pkgdiff - comparação visual de declarações de classes, japi-compliance-checker e clirr - análise de mudanças (o primeiro é escrito em perl, o segundo - em java).
linuxbuild

Você já tentou integrar algo com TeamCity? Parece que o clirr tem um plug-in Maven e também uma ferramenta chamada JAPI-Checker.
Nikolay Kuznetsov

3
Observe que o Japi-Compliance-Checker e o Pkgdiff não comparam tudo. Por exemplo, todas as implementações de método são ignoradas. Apenas assinaturas de método, remoções de método e compatibilidades de API são geradas como um relatório. Se você quiser comparar binários, pode optar por usar ferramentas como diff ou cmp ou plugin IntelliJ ou mesmo Beyond Compare!
Sriram

22

Se você selecionar dois arquivos em IntellijIdea e pressionar Ctrl + D, será mostrado o diff. Eu uso o Ultimate e não sei se vai funcionar com a edição Community .


1
@ChristianNilsson, funciona em 2018.2 no Mac 10.14 Mojave
xuesheng

Cometi o erro de selecionar a embalagem do Maven. Em Bibliotecas externas, é necessário expandir o invólucro e, em seguida, selecionar o arquivo jar. Obrigado @xuesheng
Christian Nilsson

Solução super fácil.
xandermonkey

Incrível é isso que eu estava procurando :)
z1lV3r

18
  1. Renomear .jar para .zip
  2. Extrair
  3. Descompilar arquivos de classe com jad
  4. Diferença recursiva

2
É força bruta, mas é exatamente assim que eu faria. (Exceto que posso usar jarpara extrair o conteúdo, em vez de renomear o arquivo e usá-lo pkunzip.)
David R Tribble,

2
Opcionalmente, substitua a etapa 3 por uma chamada para javap -cpara mantê-lo em bytecode (especialmente se por "alterações de método" o OP significa alterações na assinatura de um método).
Mark Peters,

Como você lidaria com corpos de método sendo movidos para cima ou para baixo no arquivo de origem? Eu acho que seria jogar o diffing de javapou jadsaída fora de sintonia.
Marcus Junius Brutus


5

Extraia cada jar para seu próprio diretório usando o comando jar com os parâmetros xvf. ou seja, jar xvf myjar.jarpara cada frasco.

Em seguida, use o comando UNIX diffpara comparar os dois diretórios. Isso mostrará as diferenças nos diretórios. Você pode usar diff -r dir1 dir2dois recurse e mostrar as diferenças nos arquivos de texto em cada diretório (.xml, .properties, etc).

Isso também mostrará se os arquivos de classe binários são diferentes. Para realmente comparar os arquivos de classe, você terá que descompilá-los conforme observado por outros.


3

Aqui está meu script para fazer o processo 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}

Posso executá-lo no Windows usando o GIT para Windows. Basta abrir um prompt de comando. Execute o bash e execute o script a partir daí.


2
Parece que você perdeu a última linha: diff -r ${EXT_DIR1} ${EXT_DIR2}ou ${DIFF} ${EXT_DIR1} ${EXT_DIR2}(se reutilizar sua variável declarada). Para quem está no cygwin, o script quase funcionou para mim, exceto duas coisas que mudei: 1) Tive que usar o javap integrado em vez do jad, porque não consigo baixar o jad (enterp. Firewall ... ); 2) como jar xfdoes't entender caminhos como /cygwin/c/rest/of/patho que é retornado por pwdno cygwin, eu tive que convertê-lo em c:/rest/of/path: JAR_DIR=${PWD}, JAR_DIR=${JAR_DIR#*/cygdrive/c},JAR_DIR="c:$JAR_DIR"
PetroCliff

Você está correto @dpg. A última linha foi $ {DIFF} $ {EXT_DIR1} $ {EXT_DIR2}
skanga

O que é jad? Não tem esse binário disponível no PATH
Filip

Jad é um descompilador Java. Acho que não é mais mantido, mas encontrei-o disponível em javadecompilers.com/jad
skanga

Caso seus argumentos (arquivos jar) estejam em um subdiretório (como foo/bar/toto.jar), você precisa adicionar o -pargumento ao comando mkdir
Duduche

2

No Linux / CygWin, um script útil que uso às vezes é:

#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 o Java Decompiler para transformar o arquivo jar em arquivo de código-fonte e, a seguir, use o WinMerge para realizar a comparação.

Você deve consultar o detentor dos direitos autorais do código-fonte, para ver se está correto fazer isso.


1

use o descompilador java e descompile todos os arquivos .class e salve todos os arquivos como a estrutura do projeto.

em seguida, use o meld diff viewer e compare como pastas.


0

Aqui está uma ferramenta aparentemente gratuita http://www.extradata.com/products/jarc/


Obrigado. Eu tentei este. Ele produz saída em XML e processamento adicional é necessário para torná-lo legível, se você tiver muitas classes em .jar
Kunal,

1
Para mim, ele reclamou da falta de um tools.jar. Eu uso o JDK, então esse não é o problema. Acho que não suporta java7.
Roel Spilker

@Tom o link está quebrado, esta resposta pode ser removida.
David Dossot

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.