122

How do I compare two .jar files? Both of them have compiled .class files.

I want the difference in terms of method changes, etc.

linuxbuild
  • 15,843
  • 6
  • 60
  • 87
Kunal
  • 2,929
  • 6
  • 21
  • 23

14 Answers14

114
linuxbuild
  • 15,843
  • 6
  • 60
  • 87
  • 1
    Andrey, what is the difference between those tools? Do they stem from the same core? – Nikolay Kuznetsov Aug 05 '14 at 20:13
  • 3
    @NikolayKuznetsov, no, these tools have different core. pkgdiff - visual comparison of classes declarations, japi-compliance-checker and clirr - analysis of changes (the first one is written in perl, the second - in java). – linuxbuild Aug 06 '14 at 06:54
  • Have you tried integrating something with TeamCity? It seems clirr has a Maven Plugin and there is also a tool called JAPI-Checker. – Nikolay Kuznetsov Aug 06 '14 at 10:48
  • 4
    Please note both Japi-Compliance-Checker and Pkgdiff do not compare everything. For example, all method implementations are ignored. Only method signatures, method removals and API compatibilities are generated as a report. If you are up to comparing binaries then you can opt to use tools like diff or cmp or IntelliJ plugin or even Beyond Compare! – Sriram May 02 '18 at 04:39
46

If you select two files in IntellijIdea and press Ctrl + Dthen it will show you the diff. I use Ultimate and don't know if it will work with Community edition.

xuesheng
  • 3,396
  • 2
  • 29
  • 38
  • 1
    @ChristianNilsson, works in 2018.2 on Mac 10.14 Mojave though – xuesheng Oct 22 '18 at 08:59
  • I made the mistake of selecting the Maven wrapper. Under _External Libraries_ one need to expand the wrapper and then select the jar-file. Thanks @xuesheng – Christian Nilsson Oct 22 '18 at 16:09
  • Super easy solution. – xandermonkey May 23 '19 at 19:36
  • Amazing that's what I was looking for :) – z1lV3r May 21 '20 at 05:37
  • Maybe they dumbed it down in the meantime. It complains that jar files are "unsupported binary files". I can list them with jar.exe, so clearly IntellijIdea isn't so intelligent these days. It also takes ages for it just list a directory in the file open dialog. An amazing piece of software. The dark grey on dark grey default theme is the usability cherry on the cake. – Fizz Feb 09 '22 at 16:39
  • After fighting the obnoxious and barely legible interface for like 10 minutes, after putting in "full IDE" as opposed to "light mode", I managed to make it open a directory. And yeah, Ctrl+D kinda works as advertised after that. Except for "// Implementation of methods is not available". No idea why not. – Fizz Feb 09 '22 at 16:49
  • And yeah I have their two plugins mentioned [here](https://www.jetbrains.com/help/idea/decompiler.html) enabled; they are so by default, but they don't work, at least not in diff mode. – Fizz Feb 09 '22 at 17:20
20
  1. Rename .jar to .zip
  2. Extract
  3. Decompile class files with jad
  4. Recursive diff
sje397
  • 41,293
  • 8
  • 87
  • 103
  • 2
    It's brute force, but that's exactly the way I'd do it. (Except that I might use `jar` to extract the contents, instead of renaming the file and using `pkunzip`.) – David R Tribble Oct 06 '10 at 01:32
  • 2
    Optionally replace step 3 with a call to `javap -c` to keep it to bytecode (especially if by "method changes" the OP meant changes to a method's signature). – Mark Peters Oct 06 '10 at 03:28
  • How would you deal with method bodies being moved up or down the source file? I think that would throw the `diff`ing of `javap` or `jad` output out of whack. – Marcus Junius Brutus Nov 15 '13 at 16:46
9

Extract each jar to it's own directory using the jar command with parameters xvf. i.e. jar xvf myjar.jar for each jar.

Then, use the UNIX command diff to compare the two directories. This will show the differences in the directories. You can use diff -r dir1 dir2 two recurse and show the differences in text files in each directory(.xml, .properties, etc).

This will also show if binary class files differ. To actually compare the class files you will have to decompile them as noted by others.

Brian
  • 20,195
  • 6
  • 34
  • 55
6

Create a folder and create another 2 folders inside it like old and new. add relevant jar files to the folders. then open the first folder using IntelliJ. after that click whatever 2 files do you want to compare and right-click and click compare archives.

Rajitha Bhanuka
  • 714
  • 10
  • 11
4

I use to ZipDiff lib (have both Java and ant API).

FoxyBOA
  • 5,788
  • 8
  • 48
  • 82
  • A useless app these days " [changed] cbk.class ( size 4895 : 4895 )" and like that for every single file. – Fizz Feb 09 '22 at 16:25
  • This does not show the diff only shows filenames that are changed – Ege Nov 29 '22 at 08:35
3

Here is my script to do the process described by 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}

I can run it on Windows using GIT for Windows. Just open a command prompt. Run bash and then execute the script from there.

Evandro Teixeira
  • 321
  • 3
  • 18
skanga
  • 351
  • 1
  • 4
  • 12
  • 2
    Seems that you missed the last line: `diff -r ${EXT_DIR1} ${EXT_DIR2}` or `${DIFF} ${EXT_DIR1} ${EXT_DIR2}` (if reuse your declared variable). For those who are on cygwin, the script almost worked for me except two things that I've changed: 1) I had to use built-in javap instead of jad, because I can't download jad (enterp. firewall ...); 2) as `jar xf` does't understand paths like `/cygwin/c/rest/of/path` which is returned by `pwd` in cygwin, I had to convert it to `c:/rest/of/path`: `JAR_DIR=${PWD}`, `JAR_DIR=${JAR_DIR#*/cygdrive/c}`, `JAR_DIR="c:$JAR_DIR"` – Peter Aug 14 '17 at 17:58
  • You are correct @dpg. The last line was ${DIFF} ${EXT_DIR1} ${EXT_DIR2} – skanga Jun 26 '18 at 01:47
  • What is `jad`? Don't have that binary available in PATH – Filip Sep 11 '19 at 18:51
  • Jad is a Java Decompiler. I think it is not maintained any longer but I found it available at http://www.javadecompilers.com/jad – skanga Sep 12 '19 at 16:08
  • In case your arguments (jar files) are in a subdirectory (like `foo/bar/toto.jar`), you need to add the `-p` argument to mkdir command – Duduche Dec 18 '19 at 07:45
2

In Linux/CygWin a handy script I use at times is:

#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
  • 669
  • 12
  • 29
2

Use Java Decompiler to turn the jar file into source code file, and then use WinMerge to perform comparison.

You should consult the copyright holder of the source code, to see whether it is OK to do so.

Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875
2

If you are using IntelliJ IDEA or Android Studio, add your jar files to a project under the libs folder. Then select the both jar files, right click then select "Compare Archives"

Mahmoud
  • 2,683
  • 1
  • 30
  • 32
1

use java decompiler and decompile all the .class files and save all files as project structure .

then use meld diff viewer and compare as folders ..

1

This application may be what you need, works great and display a simple GUI showing differences. Try Jarcomp

Zvonko
  • 181
  • 2
  • 2
0

Here's an aparently free tool http://www.extradata.com/products/jarc/

Tom
  • 43,810
  • 29
  • 138
  • 169
  • Thanks. I tried this one. It produces output in XML and further processing is required to make it readable, if you have many classes in .jar – Kunal Oct 06 '10 at 00:59
  • 1
    To me it complained about a missing tools.jar. I do use the JDK, so that's not the problem. I think it doesn't support java7. – Roel Spilker Nov 07 '13 at 16:12
  • @Tom the link is broken, this answer could be removed. – David Dossot Sep 15 '16 at 20:50
0

Please try http://www.osjava.org/jardiff/ - tool is old and the dependency list is large. From the docs, it looks like worth trying.

Jayan
  • 18,003
  • 15
  • 89
  • 143