Skip to main content

Java APIs comparison

Posted by cos on March 28, 2006 at 9:57 PM PST

Hello folks

We recently thought about an interesting approach of finding a
difference between APIs (public methods) of two versions of a Java
software. I was doing it for JDK1.5
(Tiger) and JDK1.6 (Mustang b76).

Sometime you might want to take a quick look and find out what exactly
has been changed in your (or somebody's else code) between two
versions. Why? Well, if you want to focus your test development on the
new API only it might be a very sound idea. I'd spoke about
some of other methods to help you to href="http://weblogs.java.net/blog/cos/archive/2006/03/java_quality_me_7.html">achieve
better software quality

Well, there are some methods to do so. E.g. you can use "Since" href="http://dsg.port.ac.uk/~mjeg/resources/javadiff/index.php">tags
from a Javadoc Well, good if you have any...

Or you can store your product API's snapshot like RefactorIt does. Boy, what if you didn't create this snapshot in a first
place and now you badly need one? "Sorry partner - no can do for ya..."

Anyways, the idea was on the surface as usual:

In one way or another
build a list of all public (protected/private/static/etc.) methods in
your software. You can use href="http://www.gnu.org/software/grep/">grep or href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/javap.html">javap
along with grep for these purposes. Don't forget to do this for both
versions of your application - it's about the difference, right? :-)

Now, you have these API lists, you just need to compare them. And again
it's up to you: you can use Unix diff command, Emacs ediff, or
vimdiff. I'd wrote that self-explanatory Perl script (feel free to
modify it, criticize it, or merely throw it away). Fix &open_file()'s loop if your API lists weren't created in the form of "filename:method signature" per line...

#!/usr/bin/perl

if ($#ARGV != 1) {
    print "Please supply two lists of APIs you want to compare\n";
    exit 1;
}

my %diff = ();
my $left = &open_file ($ARGV[0]);  #Presumably, the earlier version
my $right = &open_file ($ARGV[1]); #Presumably, the latest version

foreach $file (keys %$right) {
    if (!exists $left->{$file}) {
$diff{$file} =  \@{ $right->{$file} } ;
    } else {
@l_stuff = @{ $left->{$file} };
@r_stuff = @{ $right->{$file} };
foreach $r ( @r_stuff )  {
    if (&is_there($r, @l_stuff) != 1) {
push @{ $diff{$file}}, $r;
    }
}
    }
}

foreach $d (keys %diff) {
    @extract = @{ $diff{$d} };
    print "$d\n   @extract\n";
}

#=========== Some subs
sub is_there () {
    my ($search, @list) = @_;

    for (@list) {
return 1 if $_ eq $search;
    }
    return 0;
}

sub open_file () {
    local ($name) = @_;
    open FILE, $name or
        die "Can't open specified file!$name\n";
    my %ret = ();
   
    while () {
        ($key, $value) = split(':', $_);
        push @{ $ret{$key} }, $value;
    }
    return \%ret;
}

Of course, there's always an expert opinion. Or you can ask an author of an application, or eye-roll it yourself. But isn't that much simpler to load your computer with the stuff it can do better then a human being?


So, I'll let you to carry on from here...

CU,

Cos

Related Topics >>